我需要从Python执行具有2个日期参数的存储过程。我想使用数据帧行中的参数集在循环中更改参数并多次执行过程。我的代码如下;
def _get_dataset(date_param1, data_param2):
sql="exec [dbo].[SP_Name] (%s,%s)" % (date_param1,
date_param2)
cnxn = pyodbc.connect('DRIVER={SQL
Server};SERVER=xxx.xxx.xx.xx;DATABASE=db;UID=userid;PWD=password')
cursor = cnxn.cursor()
data = pd.read_sql(sql,cnxn)
return data
for i in range(len(dataframe)):
first_date = df.iloc[i][0]
second_date = df.iloc[i][1]
_get_dataset(str(first), str(second))
我得到的错误;
DatabaseError: Execution failed on sql 'exec [dbo].[SP_name] (2019-06-25,2019-06-24)': ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near '2019'. (102) (SQLExecDirectW)")
代码有什么问题?提前致谢。
答案 0 :(得分:1)
我没有用于测试的SQL Server,但是最好使用read_sql
传递参数,因为它将使用基础数据库驱动程序以安全的方式执行字符串插值:
def _get_dataset(date_param1, data_param2):
sql = "exec [dbo].[SP_Name] (?, ?)"
cnxn = pyodbc.connect(
'DRIVER={SQL Server};SERVER=xxx.xxx.xx.xx;DATABASE=db;UID=userid;PWD=password'
)
cursor = cnxn.cursor()
data = pd.read_sql(sql, cnxn, params=(date_param1, data_param2))
return data
您还可以将SQLAlchemy之类的ORM用于pass parameters in a driver-neutral way, so your code is not tied to a specific driver syntax:
In [559]: import sqlalchemy as sa
In [560]: pd.read_sql(sa.text('SELECT * FROM data where Col_1=:col1'),
.....: engine, params={'col1': 'X'})
.....:
Out[560]:
index id Date Col_1 Col_2 Col_3
0 0 26 2010-10-18 00:00:00.000000 X 27.5 1