小编典典

Pyodbc代码中不提供SQL Server临时表

sql

我正在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""")

阅读 328

收藏
2021-03-17

共1个答案

小编典典

即使这个问题有一个“解决方案”,即使用全局临时表而不是本地临时表,将来的读者也可能会从理解为什么问题首先发生的过程中受益。

当使用该表的最后一个连接关闭时,临时表将自动删除。本地临时表(#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的单独的第二个连接,而没有关闭第一个连接。

第二个连接看不到第一个连接创建的本地临时表。请注意,本地临时表仍然存在,因为第一个连接从未关闭,但是第二个连接看不到它。

但是,第二个连接 可以 看到全局临时表,因为第一个连接从未关闭过,因此全局临时表继续存在。

这种类型的行为会对ORM和其他机制产生影响,这些机制可能隐式地为执行的每个SQL语句打开和关闭与服务器的连接。

2021-03-17