我在Python中运行了一系列复杂的SQL查询,它涉及临时表。我的自动命令方法似乎并没有努力从临时表中检索数据。我在下面使用的代码段,这是我将获得的输出:
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""")
即使这个问题具有"解决方案",即使用全局临时表代替本地临时表,但未来的读者可能会受益于理解为什么问题首先发生的原因。<<<<<<<<<<
当使用上述表的最后一个连接关闭时,临时表将自动删除。本地临时表(#Temp1
)和全局临时表(##Temp1
)之间的差异是,局部临时表仅对创建它的连接可见,而现有的全局临时表可用于任何连接。
因此,使用本地临时表的以下代码将失败...
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)
...虽然使用全局温度表完全相同的代码将成功...
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 Server的独立第二个连接。
第二个连接看不到第一个连接创建的本地临时表。请注意,本地临时表仍然存在,因为第一个连接从未关闭,但是第二个连接看不到。
但是,第二个连接 can 请参阅全局温度表,因为第一个连接从未关闭,因此全局温度表继续存在。
这种类型的行为对ORM和其他机制具有启示,这些机制可能会隐式打开并关闭与服务器的连接,以执行每个SQL语句。
我向同事询问了这个现场,他的建议奏效了。因此,我去了测试问题以创建一个全局温度表,而不是本地(## temp1而不是#temp1)。然后去SQL Server测试是否实际创建了临时表。因此,我隔离了问题是第二个光标。我修改了代码以使用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查询"设置nocount"
这将输出所需的数据
SET NOCOUNT ON
对我有用。
执行方法()-SQL Server的JDBC驱动程序|微软文档
返回值
- 是的,如果语句返回结果集。
- false,如果返回更新计数或没有结果。
如果您想要结果集,则设置SET NOCOUNT ON
S在语句中所需的设置。