我正在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)之间的区别在于,本地临时表仅对创建它的连接可见,而现有的全局临时表可用于任何连接。
#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的单独的第二个连接,而没有关闭第一个连接。
pyodbc.connect
第二个连接看不到第一个连接创建的本地临时表。请注意,本地临时表仍然存在,因为第一个连接从未关闭,但是第二个连接看不到它。
但是,第二个连接 可以 看到全局临时表,因为第一个连接从未关闭过,因此全局临时表继续存在。
这种类型的行为会对ORM和其他机制产生影响,这些机制可能隐式地为执行的每个SQL语句打开和关闭与服务器的连接。