2016-02-05 75 views
0

我想在python中編寫一個SQL語句,它將表名作爲變量傳遞。但是,我得到以下錯誤:必須聲明表變量「@ P1」。我怎樣才能傳遞一個表名作爲SQL中的變量 - Python 3.4

pypyodbc.Programming Error: ('42000', '[42000]' [Miscrosoft] [SQL SERVER NATIVE CLIENT 10.0] [SQL SERVER] Must declare the table variable "@P1" 

產生錯誤的代碼是:

query = cursor.execute('''SELECT * FROM ?''', (table_variable,)) 

我還有其他的代碼,我傳遞變量使用的正常工作(下面的代碼按預期工作)的語法相同的SQL語句。

query = cursor.execute('''SELECT column_name FROM information_schema.columns WHERE table_name = ?''', (table_variable,)) 

當我使用變量傳遞表名稱時,該錯誤似乎發生。

任何幫助解決這個錯誤將不勝感激。

+1

您不能使用參數作爲表名稱。要做到這一點,需要動態的sql。 –

+0

此限制僅限於表名或是否存在其他參數無法傳遞的實例(我還沒有找到任何詳細說明這些限制的文檔)。 – DonnRK

+1

參數旨在用於謂詞來表示值。這意味着你可以在連接中使用它們,其中的子句等等。它們不是用來動態替換對象名稱的。如果你想使用參數作爲對象名稱替換,你必須使用動態sql。如果沿着這條道路走,你不會從鮑比餐桌上出門,要小心。 http://bobby-tables.com/ –

回答

2

隨着來自OP的新評論,這已經發生了很大的變化。如果你所要做的只是從每個表中獲取幾行樣本,你可以很容易地利用sys.tables目錄視圖。這將爲您的數據庫中的每個表創建一個select語句。如果您有多個模式,則可以擴展此模式以添加模式名稱。

select 'select top 10 * from ' + QUOTENAME(t.name) 
from sys.tables t 
2

你想要做的事情是不可能的。你只能傳遞值到查詢作爲參數 - 所以

SELECT * FROM @Table 

被禁止,但

SELECT * FROM TableName WHERE [email protected] 

是完全合法的。

現在,至於爲什麼它被禁止。從邏輯的角度來看,數據庫層不能緩存你想要做的事情的查詢計劃 - 參數將完全徹底地改變它發生的地方和返回的地方 - 並且不能提前保證它是什麼可以或不可以做。這就像試圖在運行時加載抽象源文件並執行它 - 混亂,不可預知,不可靠和潛在的安全漏洞。

從可靠性的觀點來看,請不要做

SELECT * FROM Table 

無論是。它使得你的代碼不易讀,因爲你看不到會在哪裏返回,但也不太可靠,因爲它可能在沒有警告的情況下改變並且破壞你的應用程序。

我知道它起初看起來很漫長,但老實說 - 編寫單個的SELECT語句指定了他們實際想要返回的字段是更好的方法。它也將使您的應用程序運行更快:-)

+1

OP想要做的事情並非不可能。您可以輕鬆利用動態sql來執行此操作。不過,我會建議這樣做並不是一個好主意,我完全同意創建個人查詢是首選方法。 –

+0

OP的問題假設SQL被解析爲一個宏語言並且動態插入了變量值,這不是真的 - 因此我爲什麼說這在SQL中是不可能的。例如,可以使用SAS或PowerShell。在SQL中執行類似於OP的嘗試代碼的唯一方法是動態SQL,我同意,但那會是類似query = cursor.execute('''EXEC(''SELECT * FROM''+?+ '')''',(table_variable,))和我們開始的很長的路,以及等待發生的壞主意和SQL注入攻擊。 – eftpotrm

+0

同意你對動態sql的擔憂,但說明這不可能是不準確的。是的,我們距離OP的開始還有很長的路要走,但那是因爲他們開始的方式不起作用。 –

1

您可以定義一個字符串變量:

table_var_str = 'Table_name' 
st = 'SELECT * FROM ' + table_var_str 
query = cursor.execute(st) 

它會解決這個問題。

您還可以設置table_var_str作爲一個列表:

table_var_str = [] 
st = [] 
for i in range(N): 
    table_var_str.append = 'Table_name' + str(i) 
    st.append('SELECT * FROM ' + table_var_str[i]) 
for j in range(J): 
    query = cursor.execute(st[j]) 

如果查詢是很長,你應該把它們寫在一條線上,而不是多線。

相關問題