Python到存储过程-要执行的第一个参数必须是字符串或Unicode查询

问题描述 投票:0回答:1

我有一个具有50多个参数的存储过程,正在SQL Server上的表中进行插入(基本上是通过存储过程插入数据框)。当我运行代码时,出现以下错误:

要执行的第一个参数必须是字符串或Unicode查询。

我尝试了以下语法,并且始终具有相同的错误:

cursor = engine.raw_connection().cursor()
#1
df.apply(lambda row: cursor.execute('EXEC MyProcedure(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',row.values), axis=1)
#2
df.apply(lambda row: cursor.execute('EXEC MyProcedure?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?',row.values), axis=1)
#3
df.apply(lambda row: cursor.execute("""EXEC MyProcedure(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",row.values), axis=1)
results = list(cursor.fetchall())
#4
df.apply(lambda row: cursor.execute(text('EXEC MyProcedure(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',row.values)), axis=1)
#5
df.apply(lambda row: cursor.execute('EXEC MyProcedure',row.values), axis=1)
cursor.close()

cursor.callproc()在这里不受支持,因此我必须通过EXECCALL请求。因此,我认为它来自于我以某种方式处理的参数,但我不知道该如何解决。由于我有57个参数,因此我试图避免尽可能多地命名所有参数...我的第一个愿望是通过将过程名称作为python函数的参数传递来使代码运行任何过程,但是由于它无法运行,我以为可以轻松一些。该过程已通过SQL Server Management直接在数据库上执行,并且工作正常。

python sql-server sqlalchemy pyodbc
1个回答
0
投票

您可以使用pyodbc的Cursor#executemany方法来简化事情:

cnxn = engine.raw_connection()
cnxn.autocommit = True
crsr = cnxn.cursor()

# prepare test environment
crsr.execute("TRUNCATE TABLE MyTable")  # clear previous test data, if any
# prepare test data
df = pd.DataFrame([(1, 'Alfa'), (2, 'Bravo')], columns=['id', 'txt'])

sql = "{CALL MyProcedure (?, ?)}"
rows = df.itertuples(index=False)
crsr.executemany(sql, rows)

# verify results
results = crsr.execute("SELECT * FROM MyTable").fetchall()
print(results)
# [(1, 'Alfa'), (2, 'Bravo')]
© www.soinside.com 2019 - 2024. All rights reserved.