如何用Python查询Wonderware实时标签值?SQL执行错误求解
错误原因与解决方法
错误原因
你执行的SQL包含多个语句:USE(切换数据库)、INSERT(插入临时表)、SELECT(查询数据)。pyodbc执行多语句时,会依次返回每个语句的执行结果:
USE和INSERT都是非查询操作,返回的是受影响行数,不是查询结果集- 当你直接调用
cur.fetchone()时,cursor当前指向的是前一个非查询语句的结果,自然会报错"Previous SQL was not a query"
另外,你的临时表和ORDER BY Seq其实是冗余的——WHERE v_Live.TagName IN ('TAG_A')已经过滤出目标标签,临时表没有起到实际作用,反而增加了不必要的语句。
解决方法
方法1:简化SQL(推荐)
直接去掉冗余的临时表和USE语句(连接数据库时可以指定目标库,不用在SQL里切换),用单查询语句:
with open_db_connection(server, 'Runtime') as conn: # 连接时直接指定Runtime数据库 cur = conn.cursor() query_string = """ SELECT TagName, DateTime, vValue FROM v_Live WHERE TagName = 'TAG_A' """ cur.execute(query_string) row = cur.fetchone() if row: print(row[1])
方法2:保留多语句,跳过非查询结果集
如果一定要保留原SQL结构,需要手动跳过前面非查询语句的结果集,再获取查询数据:
with open_db_connection(server, database) as conn: cur = conn.cursor() query_string = textwrap.dedent(""" USE Runtime DECLARE @TempTable TABLE(Seq INT IDENTITY, tempTagName NVARCHAR(256)) INSERT @TempTable(tempTagName) VALUES ('TAG_A') SELECT v_Live.TagName, DateTime, vValue FROM v_Live LEFT JOIN @TempTable ON TagName = tempTagName WHERE v_Live.TagName IN ('TAG_A') ORDER BY Seq """) cur.execute(query_string) # 跳过USE和INSERT的结果集 cur.nextset() cur.nextset() # 现在获取SELECT的结果 row = cur.fetchone() if row: print(row[1])
注意:如果你的open_db_connection没有开启MARS_Connection(多活动结果集),可能需要在连接字符串中添加MARS_Connection=Yes,否则多语句执行可能出问题。
方法3:开启连接的autocommit(可选)
部分场景下,开启autocommit可以避免多语句的结果集干扰,在创建连接时设置:
# 假设open_db_connection内部可以配置连接参数 def open_db_connection(server, database): conn_str = f"DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={server};DATABASE={database};Trusted_Connection=yes;MARS_Connection=Yes" conn = pyodbc.connect(conn_str, autocommit=True) return conn
内容的提问来源于stack exchange,提问作者Nili
相关产品推荐
相关产品推荐

