2013-02-01 61 views
2

使用Informix 11.7,我想在select語句這樣執行與JDBC位置參數的INSERT SELECT查詢:INSERT SELECT不工作

INSERT INTO table1(id, code, label) 
SELECT ?, ?, ? FROM table2 
WHERE ... 

參數設置如下:

stmt.setString(1, "auniqueid"); 
stmt.setString(2, "code"); 
stmt.setString(3, "coollabel"); 

我收到以下錯誤:在線程「主要」值java.sql.SQLException

例外:發生語法錯誤。

當位置參數「?」放在其他地方工作正常。我沒有使用PostgreSQL的這個問題。我的查詢有什麼問題?我使用Informix JDBC Driver v3.70 JC1。

感謝您的幫助。

回答

1

警告:我使用Informix沒有經驗,答案是基於一般觀察

當指定參數數據庫需要知道每個參數的類型。如果在選擇列表中出現參數,則數據庫無法推斷參數的類型。有些數據庫可能會延遲這個決定,直到它實際接收參數爲止,但大多數數據庫都需要在解析時知道這一點。這可能是您收到錯誤的原因。

某些數據庫 - 我不知道這是否適用於Informix - 允許您投射參數。例如:

SELECT CAST(? AS VARCHAR(20)), CAST(? AS VARCHAR(10)), CAST(? AS VARCHAR(5)) FROM ... 

在這種情況下,數據庫將能夠推斷出參數類型並能夠正確解析查詢。

有了這個,我假設你並沒有試圖使用參數爲選擇列表指定列名,因爲這是不可能的。

2

您是否期望獲取通過佔位符指定的列名稱?如果是這樣,你就隱藏起來了;您不能使用佔位符作爲查詢的結構元素,例如列名或表名。他們只能取代價值。如果您希望動態SQL指定列,請使用動態SQL;創建一個字符串的內容:

INSERT INTO table1(id, code, label) 
    SELECT auniqueid, code, coollabel 
     FROM table2 
    WHERE ... 

並與此合作。

如果這些佔位符將成爲值,那麼您會一遍又一遍地插入相同的值,一次查詢返回的每一行,這通常不是您想要的;你只需在VALUES子句中插入一行,其中允許佔位符:

INSERT INTO table1(id, code, label) VALUES(?, ?, ?); 

這樣可以正常工作。

AFAIK,此行爲符合SQL標準。如果它在PostgreSQL中的工作方式不同,那麼PostgreSQL提供了對該標準的擴展。

+0

不,這不是我想要做的。我想通過佔位符指定列值?並一次插入許多行以提高性能。事實上,我的SELECT查詢有點複雜,有一個NOT EXISTS子句可以過濾結果。當然,它可以使用INSERT VALUES語法,但我必須將我的過程分爲兩部分:首先是SELECT查詢,它將返回要插入的值,然後是多個INSERT VALUES查詢,循環SELECT結果。 – mishka

+0

好的;我不確定你爲什麼要重複插入相同的值,但如果這是你想要的,那麼投射佔位符將會起作用(如果Mark Rotteveel尚未提出建議,這將是我的下一個建議,儘管我可能已經試圖用'?VARCHAR(16)'符號而不是SQL標準'CAST(?AS VARCHAR(16))')來建議。所以,你沒事。 (簡單地解釋一下你想要實現的效果,以便像這樣的答案走彎路,這會很有幫助。你的問題沒有提到你試圖插入相同數據的許多副本。) –

+0

對不起,我缺乏的清晰度。事實上,我不想一次又一次地插入完全相同的值。我的SELECT子句是這樣的:SELECT table2.id,'fixedvalue','fixedvalue'。我finnaly選擇手工構建我的查詢,不使用JDBC佔位符,以避免SQL類型之間的可移植性問題,並防止數據庫架構修改。無論如何,感謝您的幫助! – mishka