Ben*_*ine 9 python sql sql-server stored-procedures pyodbc
我有一个python脚本使用pyodbc来调用MSSQL存储过程,如下所示:
cursor.execute("exec MyProcedure @param1 = '" + myparam + "'")
Run Code Online (Sandbox Code Playgroud)
我在循环中调用这个存储过程,我注意到有时,在最后一次执行完程序之前,会再次调用该过程.我知道这个,因为如果我添加这条线
time.sleep(1)
Run Code Online (Sandbox Code Playgroud)
在执行行之后,一切正常.
有没有更优雅,更省时的方式来说,"睡觉直到执行完毕"?
更新(Divij的解决方案):此代码目前不适用于我:
from tornado import gen
import pyodbc
@gen.engine
def func(*args, **kwargs):
# connect to db
cnxn_str = """
Driver={SQL Server Native Client 11.0};
Server=172.16.111.235\SQLEXPRESS;
Database=CellTestData2;
UID=sa;
PWD=Welcome!;
"""
cnxn = pyodbc.connect(cnxn_str)
cnxn.autocommit = True
cursor = cnxn.cursor()
for _ in range(5):
yield gen.Task(cursor.execute, 'exec longtest')
return
func()
Run Code Online (Sandbox Code Playgroud)
我知道这很旧,但我只是花了几个小时试图弄清楚如何让我的 Python 代码等待 MSSQL 上的存储过程完成。
问题不在于异步调用。
解决此问题的关键是确保您的过程在完成运行之前不会返回任何消息。否则,PYDOBC 将来自 proc 的第一条消息解释为它的结束。
运行您的程序SET NOCOUNT ON
。此外,请确保任何PRINT
语句或RAISERROR
您可能用于调试的语句都被静音。
@muted
向您的 proc添加一个 BIT 参数,如果它是0
.
在我的特殊情况下,我正在执行一个 proc 来处理加载的表,并且我的应用程序在该过程完成运行之前退出并关闭游标,因为我正在获取行计数和调试消息。
总而言之,按照以下方式做一些事情
cursor.execute('SET NOCOUNT ON; EXEC schema.proc @muted = 1')
并且 PYODBC 将等待 proc 完成。
这是我的解决方法:
在数据库中,我创建了一个名为 的表RunningStatus
,其中只有一个字段 ,status
它是bit
,并且只有一行,最初设置为 0。
在存储过程的开头,我执行以下行
update RunningStatus set status = 1;
Run Code Online (Sandbox Code Playgroud)
在存储过程的末尾,
update RunningStatus set status = 0;
Run Code Online (Sandbox Code Playgroud)
在我的 Python 脚本中,我打开一个指向同一数据库的新连接和游标。在我的execute
行之后,我只需添加
while 1:
q = status_check_cursor.execute('select status from RunningStatus').fetchone()
if q[0] == 0:
break
Run Code Online (Sandbox Code Playgroud)
您需要建立一个新的连接和游标,因为来自旧连接的任何调用都会中断存储过程,并可能导致status
永远不会返回到 0。
它有点笨拙,但对我来说非常有用!
归档时间: |
|
查看次数: |
5515 次 |
最近记录: |