如何解决有条件地从 Python 在 SQL 中创建临时表
在大量查询中,我试图在 sql 中创建一个临时表(如果它尚不存在)。显然,您可以删除第二个 CREATE TABLE
语句。但是,我正在构建的查询是动态的,可能会或可能不会出现第一个 CREATE TABLE
语句。
我可以让以下示例/测试查询在 Microsoft sql Server Management Studio 中工作。它是在 this SO question/answer
的帮助下创建的SET NOCOUNT ON;
DROP TABLE IF EXISTS #temp_sample;
CREATE TABLE #temp_sample (
id VARCHAR(15) NOT NULL,datetime DATETIME,location VARCHAR(255)
);
GO
INSERT INTO #temp_sample (id,datetime,location)
VALUES ('ABC','2021-06-04 15:52:44','PENNSYLVANIA'),('123','2021-06-04 15:52:49','PENNSYLVANIA');
IF (OBJECT_ID('tempdb..#temp_sample') IS NULL)
BEGIN
CREATE TABLE #temp_sample (
id VARCHAR(15) NOT NULL,location VARCHAR(255)
);
END
ELSE
PRINT '#temp_sample already exists... skipping'
GO
SELECT * FROM #temp_sample
当我在同一个数据库中运行以下代码,但使用 pandas.io.sql.read_sql
和 pypyodbc
时,我得到了随附的回溯:
import pypyodbc
import pandas.io.sql as psql
connection_string = 'DSN=dsn_name;UID=username;PWD=password;app=app_name;'
cnxn = pypyodbc.connect(connection_string)
temp_db_query = '''
SET NOCOUNT ON;
DROP TABLE IF EXISTS #temp_sample;
CREATE TABLE #temp_sample (
id VARCHAR(15) NOT NULL,location VARCHAR(255)
);
GO
INSERT INTO #temp_sample (id,location)
VALUES ('ABC','PENNSYLVANIA');
IF (OBJECT_ID('tempdb..#temp_sample') IS NULL)
BEGIN
CREATE TABLE #temp_sample (
id VARCHAR(15) NOT NULL,location VARCHAR(255)
);
END
ELSE
PRINT '#temp_sample already exists... skipping'
GO
SELECT * FROM #temp_sample
'''
df = psql.read_sql(temp_db_query,cnxn)
cnxn.close()
Traceback (most recent call last):
File "/Users/user/miniconda3/envs/myenv/lib/python3.6/site-packages/pandas/io/sql.py",line 1595,in execute
cur.execute(*args)
File "/Users/user/miniconda3/envs/myenv/lib/python3.6/site-packages/pypyodbc.py",line 1626,in execute
self.execdirect(query_string)
File "/Users/user/miniconda3/envs/myenv/lib/python3.6/site-packages/pypyodbc.py",line 1652,in execdirect
check_success(self,ret)
File "/Users/user/miniconda3/envs/myenv/lib/python3.6/site-packages/pypyodbc.py",line 1007,in check_success
ctrl_err(sql_HANDLE_STMT,ODBC_obj.stmt_h,ret,ODBC_obj.ansi)
File "/Users/user/miniconda3/envs/myenv/lib/python3.6/site-packages/pypyodbc.py",line 975,in ctrl_err
raise ProgrammingError(state,err_text)
pypyodbc.ProgrammingError: ('42S01',"[42S01] [Microsoft][ODBC Driver 17 for sql Server][sql Server]There is already an object named '#temp_sample' in the database.")
有人可以帮助我使用 pandas.io.sql.read_sql
进行查询吗?我愿意切换到另一个 odbc 包,如 pyodbc
、turbodbc
等。
======== 更新 ========
根据其中一条评论,我尝试更改 IF
语句中的逻辑,因为在使用 ODBC 时,它似乎被标记为 TRUE。这个版本也适用于 MSSMS,但在 Python 中给了我同样的错误。还有其他版本有效吗?
IF EXISTS (SELECT * FROM tempdb.sys.tables WHERE name LIKE '#temp_sample%')
PRINT '#temp_sample already exists... skipping'
ELSE
BEGIN
CREATE TABLE #temp_sample (
id VARCHAR(15) NOT NULL,location VARCHAR(255)
);
END
GO
解决方法
这是一个批处理编译错误。当您删除 GO
时,您必须使用它来编译它,那么同一个临时表有两个 CREATE TABLE
语句,它们不会解析和编译。 EG 这个批次产生同样的错误:
CREATE TABLE #temp_sample (id int)
if 1=0
begin
CREATE TABLE #temp_sample (id int)
end
要修复,只需删除第二个 CREATE TABLE
,因为它无论如何都没有必要。 EG
SET NOCOUNT ON;
DROP TABLE IF EXISTS #temp_sample;
CREATE TABLE #temp_sample (
id VARCHAR(15) NOT NULL,datetime DATETIME,location VARCHAR(255)
);
INSERT INTO #temp_sample (id,datetime,location)
VALUES ('ABC','2021-06-04 15:52:44','PENNSYLVANIA'),('123','2021-06-04 15:52:49','PENNSYLVANIA');
SELECT * FROM #temp_sample
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。