2013-09-22 30 views
1

我試圖移植一個概念,該概念在我用於SQL存儲過程的Java代碼中使用,並且我不確定它是否可行。更新存儲過程中的不同列

本質上,如果我有一個包含10列的表,我希望能夠每次更新來自同一存儲過程的列的不同組合。即在Java中,我會傳遞一個包含我想要更新的值的映射,並遍歷它們並更新緩存中的每個鍵值。

這樣做的好處是無需更改方法簽名以包含每個列名稱,也不必爲每個變量執行空檢查以確定是否應該更新。我不確定這是否可行,或者某些數據庫服務器是否有能力(即PostgreSQL,Oracle,MySQL),或者他們都有能力,但我無法弄清楚語法。

+0

你可以發佈一個Java代碼的例子,以便更清楚你想要實現什麼。 – calcinai

+0

這可以在您提到的任何DBMS中使用動態SQL來完成。 –

回答

1

在SQL Server中,下面的程序將工作假設像這樣的表:

CREATE TABLE MyBigTable(
    ID INT NOT NULL PRIMARY KEY, 
    COLUMNA VARCHAR(100) NOT NULL, 
    COLUMNB VARCHAR(100) NOT NULL 
) 

GO 

CREATE PROCEDURE UpdateMyBigTable(@ID INT, @ColumnAValue VARCHAR(100)=NULL, @ColumnBValue VARCHAR(100)=NULL) 
AS BEGIN 
UPDATE MyBigTable 
    SET COLUMNA = CASE WHEN @ColumnAValue IS NULL THEN COLUMNA ELSE @ColumnAValue END, 
    COLUMNB = CASE WHEN @ColumnBValue IS NULL THEN COLUMNB ELSE @ColumnBValue END 
WHERE ID = @ID 
    AND ((COLUMNA <> @ColumnAValue AND @ColumnAValue IS NOT NULL) OR (COLUMNB <> @ColumnBValue AND @ColumnBValue IS NOT NULL)); 
END 

GO 

然而,這實際上並沒有通過這就是你問的領域不勝枚舉。沒有進入動態SQL,這在SQL Server中很難做到。

+1

在第二種情況下,您如何區分要設置爲NULL的列和不想更改值的列? –

+0

你說得對。我會去解決這個問題。如果你打算允許NULL,解決方案變得複雜得多,因爲我想你必須進入限制值,例如發送低ASCII字符。在重新閱讀時,無論如何,任何解決方案都不適用於OP所述的情況,這就是要求循環遍歷列的方法。 – NYCdotNet

+0

如果你這樣做,你實際上更新的價值 - 即使有自己的現有價值。從內存中,這會導致索引重新計算,因此比開始時計算條件語句要慢。 –

0

爲獲得最佳性能,請對每個可能的查詢參數組合使用動態SQL或帶有SQL語句的IF語句。

如果您可以對每種可能的解決方案進行IF語句處理,請參閱以下內容 - 它是穩定,安全和高性能的。

如果您有太多參數,請使用動態SQL - 您可以在存儲過程或更早版本中生成動態SQL,但一定要避免使用SQL injection issues

您的問題與Erland Sommarskog涵蓋的dynamic search問題非常相似。

性能方面,SQL Server將爲每個可能的動態查詢類型創建一個執行計劃,因此性能將類似於使用IF語句選擇每個可能的SQL語句。

這與使用COLUMNB = CASE WHEN @COLUMNB IS NULL THEN COLUMNB ELSE @COLUMNB END只有一個執行計劃,因此通常執行計劃很差(取決於DB中的where子句和索引)以及性能較差形成鮮明對比。