SQL 服务器温度 table 在 pyodbc 代码中不可用
SQL Server temp table not available in pyodbc code
我 运行 在 python 中进行了一系列复杂的 sql 查询,它涉及临时 tables。我的自动提交方法似乎无法从临时 table 检索数据。我在下面使用的代码片段,这是我得到的输出:
testQuery="""
Select top 10 *
INTO #Temp1
FROM Table1 t1
JOIN Table2 t2
on t1.key=t2.key
"""
cnxn=pyodbc.connect(r'DRIVER={SQL Server Native Client 11.0};SERVER=server;DATABASE=DB;UID=UID;PWD=PWD')
cnxn.autocommit=True
cursor=cnxn.cursor()
cursor.execute(testQuery)
cursor.execute("""Select top 10 * from #Temp1""")
<pyodbc.Cursor at 0x8f78930>
cnxn=pyodbc.connect(r'DRIVER={SQL Server Native Client 11.0};SERVER=server;DATABASE=DB;UID=UID;PWD=PWD')
cnxn.autocommit=True
cursor=cnxn.cursor()
cursor.execute(testQuery)
cursor.execute("""Select top 10 * from #Temp1""")
我就这个直播问了一位同事,他的建议奏效了。所以我去更改了 testQuery 以创建一个全局温度 table 而不是本地温度(##Temp1 而不是 #Temp1)。然后去 sql 服务器测试临时文件 table 是否真的被创建了——它是。所以我发现问题出在第二个 cursor.execute 语句上。我修改了代码以使用 pandas read_sql_query 代替,一切都成功了!下面是我使用的代码:
testQuery="""
Select top 10 *
INTO ##Temp1
FROM Table1 t1
JOIN Table2 t2
on t1.key=t2.key
"""
cnxn=pyodbc.connect(r'DRIVER={SQL Server Native Client 11.0};SERVER=server;DATABASE=DB;UID=UID;PWD=PWD')
cnxn.autocommit=True
cursor=cnxn.cursor()
cursor.execute(testQuery)
cnxn.commit()
query1="Select top 10 * from ##Temp1"
data1=pd.read_sql_query(query1, cnxn)
data1[:10]
解决此问题的最佳方法是开始您的 SQL 查询:
"SET NOCOUNT ON"
这将输出所需的数据
即使这个问题有一个 "solution",即使用全局温度 table 而不是本地温度 table,未来的读者可能会受益于理解为什么问题发生在第一名.
当使用上述 table 的最后一个连接关闭时,临时 table 会自动删除。局部温度 table (#Temp1
) 和全局温度 table (##Temp1
) 的区别在于局部温度 table 仅对连接可见创建它的人,而现有的全局临时文件 table 可用于任何连接。
因此使用本地临时文件的以下代码 table 将失败 ...
conn = pyodbc.connect(conn_str, autocommit=True)
crsr = conn.cursor()
sql = """\
SELECT 1 AS foo, 2 AS bar INTO #Temp1
"""
crsr.execute(sql)
conn = pyodbc.connect(conn_str, autocommit=True)
crsr = conn.cursor()
sql = """\
SELECT foo, bar FROM #Temp1
"""
crsr.execute(sql)
row = crsr.fetchone()
print(row)
...而使用全局温度 table 的完全相同的代码将成功...
conn = pyodbc.connect(conn_str, autocommit=True)
crsr = conn.cursor()
sql = """\
SELECT 1 AS foo, 2 AS bar INTO ##Temp1
"""
crsr.execute(sql)
conn = pyodbc.connect(conn_str, autocommit=True)
crsr = conn.cursor()
sql = """\
SELECT foo, bar FROM ##Temp1
"""
crsr.execute(sql)
row = crsr.fetchone()
print(row)
... 因为第二个 pyodbc.connect
调用打开了与 SQL 服务器的单独的第二个连接,而没有关闭第一个连接。
第二个连接无法看到第一个连接创建的本地临时文件 table。请注意,本地临时文件 table 仍然存在,因为第一个连接从未关闭,但第二个连接看不到它。
但是,第二个连接 可以 看到全局临时文件 table 因为第一个连接从未关闭,因此全局临时文件 table 继续存在.
这种类型的行为对 ORM 和其他机制有影响,这些机制可能会为服务器执行的每个 SQL 语句隐式打开和关闭与服务器的连接。
SET NOCOUNT ON
对我有用。
执行方法() - JDBC Driver for SQL Server | Microsoft Docs
Return 值
- true,如果语句returns一个结果集。
- false,如果 returns 更新计数或没有结果。
如果您想要一个结果集,那么设置 SET NOCOUNT ON
就是您在语句中需要的设置。
我 运行 在 python 中进行了一系列复杂的 sql 查询,它涉及临时 tables。我的自动提交方法似乎无法从临时 table 检索数据。我在下面使用的代码片段,这是我得到的输出:
testQuery="""
Select top 10 *
INTO #Temp1
FROM Table1 t1
JOIN Table2 t2
on t1.key=t2.key
"""
cnxn=pyodbc.connect(r'DRIVER={SQL Server Native Client 11.0};SERVER=server;DATABASE=DB;UID=UID;PWD=PWD')
cnxn.autocommit=True
cursor=cnxn.cursor()
cursor.execute(testQuery)
cursor.execute("""Select top 10 * from #Temp1""")
<pyodbc.Cursor at 0x8f78930>
cnxn=pyodbc.connect(r'DRIVER={SQL Server Native Client 11.0};SERVER=server;DATABASE=DB;UID=UID;PWD=PWD')
cnxn.autocommit=True
cursor=cnxn.cursor()
cursor.execute(testQuery)
cursor.execute("""Select top 10 * from #Temp1""")
我就这个直播问了一位同事,他的建议奏效了。所以我去更改了 testQuery 以创建一个全局温度 table 而不是本地温度(##Temp1 而不是 #Temp1)。然后去 sql 服务器测试临时文件 table 是否真的被创建了——它是。所以我发现问题出在第二个 cursor.execute 语句上。我修改了代码以使用 pandas read_sql_query 代替,一切都成功了!下面是我使用的代码:
testQuery="""
Select top 10 *
INTO ##Temp1
FROM Table1 t1
JOIN Table2 t2
on t1.key=t2.key
"""
cnxn=pyodbc.connect(r'DRIVER={SQL Server Native Client 11.0};SERVER=server;DATABASE=DB;UID=UID;PWD=PWD')
cnxn.autocommit=True
cursor=cnxn.cursor()
cursor.execute(testQuery)
cnxn.commit()
query1="Select top 10 * from ##Temp1"
data1=pd.read_sql_query(query1, cnxn)
data1[:10]
解决此问题的最佳方法是开始您的 SQL 查询:
"SET NOCOUNT ON"
这将输出所需的数据
即使这个问题有一个 "solution",即使用全局温度 table 而不是本地温度 table,未来的读者可能会受益于理解为什么问题发生在第一名.
当使用上述 table 的最后一个连接关闭时,临时 table 会自动删除。局部温度 table (#Temp1
) 和全局温度 table (##Temp1
) 的区别在于局部温度 table 仅对连接可见创建它的人,而现有的全局临时文件 table 可用于任何连接。
因此使用本地临时文件的以下代码 table 将失败 ...
conn = pyodbc.connect(conn_str, autocommit=True)
crsr = conn.cursor()
sql = """\
SELECT 1 AS foo, 2 AS bar INTO #Temp1
"""
crsr.execute(sql)
conn = pyodbc.connect(conn_str, autocommit=True)
crsr = conn.cursor()
sql = """\
SELECT foo, bar FROM #Temp1
"""
crsr.execute(sql)
row = crsr.fetchone()
print(row)
...而使用全局温度 table 的完全相同的代码将成功...
conn = pyodbc.connect(conn_str, autocommit=True)
crsr = conn.cursor()
sql = """\
SELECT 1 AS foo, 2 AS bar INTO ##Temp1
"""
crsr.execute(sql)
conn = pyodbc.connect(conn_str, autocommit=True)
crsr = conn.cursor()
sql = """\
SELECT foo, bar FROM ##Temp1
"""
crsr.execute(sql)
row = crsr.fetchone()
print(row)
... 因为第二个 pyodbc.connect
调用打开了与 SQL 服务器的单独的第二个连接,而没有关闭第一个连接。
第二个连接无法看到第一个连接创建的本地临时文件 table。请注意,本地临时文件 table 仍然存在,因为第一个连接从未关闭,但第二个连接看不到它。
但是,第二个连接 可以 看到全局临时文件 table 因为第一个连接从未关闭,因此全局临时文件 table 继续存在.
这种类型的行为对 ORM 和其他机制有影响,这些机制可能会为服务器执行的每个 SQL 语句隐式打开和关闭与服务器的连接。
SET NOCOUNT ON
对我有用。
执行方法() - JDBC Driver for SQL Server | Microsoft Docs
Return 值
- true,如果语句returns一个结果集。
- false,如果 returns 更新计数或没有结果。
如果您想要一个结果集,那么设置 SET NOCOUNT ON
就是您在语句中需要的设置。