簡體   English   中英

有條件地從 Python 在 SQL 中創建臨時表

[英]Conditionally Create Temp Table in SQL from Python

在大量查詢中,我試圖在 SQL 中創建一個臨時表(如果它尚不存在)。 顯然,您可以刪除第二個CREATE TABLE語句。 但是,我正在構建的查詢是動態的,可能存在也可能不存在第一個CREATE TABLE語句。

我可以讓以下示例/測試查詢在 Microsoft SQL Server Management Studio 中工作。 它是在此 SO 問題/答案的幫助下創建的

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,
            datetime DATETIME,
            location VARCHAR(255)
        );
    END
ELSE 
    PRINT '#temp_sample already exists... skipping'
GO

SELECT * FROM #temp_sample

當我在同一個數據庫中運行以下代碼,但使用pandas.io.sql.read_sqlpypyodbc我得到了隨附的回溯:

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,
        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,
                datetime DATETIME,
                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 包,如pyodbcturbodbc等。

======== 更新 ========

根據其中一條評論,我嘗試更改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,
                datetime DATETIME,
                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 ,因為無論如何它都是不必要的。 例如

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM