簡體   English   中英

在SQL服務器中執行多變量查詢使用Python cursor

[英]Execute multiple variable query in SQL Server using Python cursor

我正在嘗試使用 pymssql 庫在 SQL 服務器中執行多個查詢。

這是我的代碼:

cur = conn.cursor()
cur.execute("DECLARE @begin_time datetime, @end_time datetime, @from_lsn binary(10), @to_lsn binary(10);  
             SET @begin_time = DATEADD(day, -1, GETDATE()) ;  
             SET @end_time = GETDATE(); 
             SET @from_lsn = sys.fn_cdc_map_time_to_lsn('smallest greater than or equal', @begin_time);  
             SET @to_lsn = sys.fn_cdc_map_time_to_lsn('largest less than or equal', @end_time);
             SELECT * FROM cdc.fn_cdc_get_net_changes_dbo_users(@from_lsn, @to_lsn, 'all');")
output = cur.fetchall()
print(output)
conn.close()

代碼運行良好並獲取結果,但是當我使用 Python 庫計算日期並將其傳遞給代碼時,出現錯誤。

示例代碼

from datetime import datetime, timedelta
end_date = datetime.now()
start_date = datetime.now() + timedelta(hours=-1)

cur = conn.cursor()
query =  f"""DECLARE @begin_time datetime, @end_time datetime, @from_lsn binary(10), @to_lsn binary(10);  
                SET @begin_time = {start_date};  
                SET @end_time = {end_date}; 
                SET @from_lsn = sys.fn_cdc_map_time_to_lsn('smallest greater than or equal', @begin_time);  
                SET @to_lsn = sys.fn_cdc_map_time_to_lsn('largest less than or equal', @end_time); 
                SELECT * FROM cdc.fn_cdc_get_all_changes_dbo_users (@from_lsn, @to_lsn, 'all');"""
print(query)
cur.execute(query)
output = cur.fetchall()
print(output)
conn.close()

錯誤:

ProgrammingError : (102, '11' 附近的語法不正確。

DB-Lib 錯誤消息 20018,嚴重性 15:
一般 SQL 服務器錯誤:檢查來自 SQL 服務器的消息

我不確定我在這里做錯了什么。 如果有人可以幫助我並解釋這個問題,我將不勝感激。

考慮時間變量的實際 SQL 參數化,而不是字符串插值或與 F 字符串的連接,這對於將值從應用程序層傳遞到后端數據庫通常是不安全或不高效的。 pymssql支持parameters Python 的datetime.datetime應該轉換為 MSSQL 的DATETIME

# PREPARED STATEMENTS WITH %s PLACEHOLDERS
query = """DECLARE @begin_time datetime, @end_time datetime, @from_lsn binary(10), @to_lsn binary(10);  
           SET @begin_time = %s;  
           SET @end_time = %s; 
           SET @from_lsn = sys.fn_cdc_map_time_to_lsn('smallest greater than or equal', @begin_time);  
           SET @to_lsn = sys.fn_cdc_map_time_to_lsn('largest less than or equal', @end_time); 
           SELECT * FROM cdc.fn_cdc_get_all_changes_dbo_users (@from_lsn, @to_lsn, 'all');
        """
print(query)

# EXECUTE QUERY WITH BINDED PARAMS
cur.execute(query, [start_date, end_date])

事實上,您可以縮短查詢,因為參數不需要聲明:

# PREPARED STATEMENTS WITH %s PLACEHOLDERS
query = """DECLARE @from_lsn binary(10), @to_lsn binary(10);
           SET @from_lsn = sys.fn_cdc_map_time_to_lsn('smallest greater than or equal', %s);  
           SET @to_lsn = sys.fn_cdc_map_time_to_lsn('largest less than or equal', %s); 
           SELECT * FROM cdc.fn_cdc_get_all_changes_dbo_users (@from_lsn, @to_lsn, 'all');
        """

順便說一下,請注意pymmsql不再是一個維護的庫。 考慮pyodbc以獲得最安全、更新的 DB-API for Python-SQL Server 連接。 但請注意 pyodbc 的參數占位符是 qmarks ? 而不是%s (與大多數 Python DB-API 不同)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM