2011-10-01 239 views
0

我想寫一個UPDATE查詢,可以檢查其中一個字段的空值。我有三個條件,兩個是強制性的,三個領域。 itemCode和itemCheckDigit將始終存在,itemSuffix可能爲空。更新語句不執行

可能有多個記錄,其中itemCode和itemCheckDigit在一起等於其他記錄,itemSuffix是unquie標識符,只有一個實例將存在,但where itemSuffix是Null且永遠不會被複制。

UPDATE item 
SET   itemImageFileName = ''' + @fileName + ''' 
WHERE  (itemCode = ''' + @itemCode5 + ''') AND (itemCheckDigit = ''' + @itemCkDigit + ''') AND (itemSuffix IS NULL); 

這是我認爲我想要做的,但它不工作。

+0

很明顯的東西在你的WHERE子句限制的更新。暫時將其轉換爲SELECT並從WHERE中刪除謂詞,直到獲得結果。那麼你將會隔離這個問題。 –

+1

我想我確定了你的問題的一部分,但如果你想用你提供的代碼同步你的描述(列不匹配),我們可以通過你的NULL比較問題。 – billinkc

+0

現在嘗試您的建議,我懷疑它與Null有關。這是檢查字段中的空值的適當語法? – htm11h

回答

2

你的問題是,你是纏繞你的參數刻度標記在你的聲明,所以當它的評價是尋找從項目表,其中itemCode是「玩具」(注意單引號)

字符串連接東西你正在做的是如何將不好的參數添加到他們的動態查詢中。相反,採取刻度線出像這樣

UPDATE 
    item 
SET 
    itemImageFileName = @fileName 
WHERE 
    (itemCode = @itemCode5) 
    AND (itemCheckDigit = @itemCkDigit) 
    AND (itemSuffix IS NULL); 

要處理可選搜索參數,本文由比爾·格拉齊亞諾是優秀:Using Dynamic SQL in Stored Procedures。我發現在避免設置重新編譯選項的查詢重新編譯和避免表掃描之間取得了很好的平衡。

請享用此代碼。它創建一個臨時表來模擬您的實際項目表並使用8行數據加載它。我聲明瞭一些你很可能不需要做的參數,因爲ado.net庫會爲你做一些魔術。

根據爲前3個參數提供的值,您將獲得與表中某一行的等效匹配,並將更新文件名值。在我的示例中,您將看到所有NULL行將從f07.bar更改爲f07.bar.updated。

打印語句不是必需的,但我把它放在那裏,以便您可以看到構建的查詢作爲了解模式的幫助。

IF NOT EXISTS (SELECT * FROM tempdb.sys.tables T WHERE T.name like '%#item%') 
BEGIN 
    CREATE TABLE 
     #item 
    (
     itemid int identity(1,1) NOT NULL PRIMARY KEY 
    , itemCode varchar(10) NULL 
    , itemCheckDigit varchar(10) NULL 
    , itemSuffx varchar(10) NULL 
    , itemImageFileName varchar(50) 
    ) 
    INSERT INTO 
     #item 
    -- 2008+ 
    --table value constructor (VALUES allows for anonymous table declaration) {2008} 
    --http://technet.microsoft.com/en-us/library/dd776382.aspx 
    VALUES 
     ('abc', 'X', 'cba', 'f00.bar') 
    , ('ac', NULL, 'ca', 'f01.bar') 
    , ('ab', 'x', NULL, 'f02.bar') 
    , ('a', NULL, NULL, 'f03.bar') 

    , (NULL, 'X', 'cba', 'f04.bar') 
    , (NULL, NULL, 'ca', 'f05.bar') 
    , (NULL, 'x', NULL, 'f06.bar') 
    , (NULL, NULL, NULL, 'f07.bar') 
END 

SELECT * 
FROM #item I; 

-- These correspond to your parameters 
DECLARE 
    @itemCode5 varchar(10) 
, @itemCkDigit varchar(10) 
, @itemSuffx varchar(10) 
, @fileName varchar(50) 

-- Using the above table, populate these as 
-- you see fit to verify it's behaving as expected 
-- This example is for all NULLs 
SELECT 
    @itemCode5 = NULL 
, @itemCkDigit = NULL 
, @itemSuffx = NULL 
, @fileName = 'f07.bar.updated' 


DECLARE 
    @query nvarchar(max) 

SET 
    @query = N' 
UPDATE 
    I 
SET 
    itemImageFileName = @fileName 
FROM 
    #item I 
WHERE 
    1=1 
' ; 


IF @itemCode5 IS NOT NULL 
BEGIN 
    SET @query += ' AND I.itemCode = @itemCode5 ' + char(13) 
END 
ELSE 
BEGIN 
    -- These else clauses may not be neccessary depending on 
    -- what your data looks like and your intentions 
    SET @query += ' AND I.itemCode IS NULL ' + char(13) 
END 

IF @itemCkDigit IS NOT NULL 
BEGIN 
    SET @query += ' AND I.itemCheckDigit = @itemCkDigit ' + char(13) 
END 
ELSE 
BEGIN 
    SET @query += ' AND I.itemCheckDigit IS NULL ' + char(13) 
END 

IF @itemSuffx IS NOT NULL 
BEGIN 
    SET @query += ' AND I.itemSuffx = @itemSuffx ' + char(13) 
END 
ELSE 
BEGIN 
    SET @query += ' AND I.itemSuffx IS NULL ' + char(13) 
END 

PRINT @query 

EXECUTE sp_executeSQL @query 
, N'@itemCode5 varchar(10), @itemCkDigit varchar(10), @itemSuffx varchar(10), @fileName varchar(50)' 
, @itemCode5 = @itemCode5 
, @itemCkDigit = @itemCkDigit 
, @itemSuffx = @itemSuffx 
, @fileName = @fileName; 

-- observe that all null row is now displaying 
-- f07.bar.updated instead of f07.bar 
SELECT * 
FROM #item I; 

之前

itemid itemCode itemCheckDigit itemSuffx itemImageFileName 
1  abc  X    cba   f00.bar 
2  ac   NULL    ca   f01.bar 
3  ab   x    NULL   f02.bar 
4  a   NULL    NULL   f03.bar 
5  NULL  X    cba   f04.bar 
6  NULL  NULL    ca   f05.bar 
7  NULL  x    NULL   f06.bar 
8  NULL  NULL    NULL   f07.bar 

itemid itemCode itemCheckDigit itemSuffx itemImageFileName 
1  abc  X    cba   f00.bar 
2  ac   NULL    ca   f01.bar 
3  ab   x    NULL   f02.bar 
4  a   NULL    NULL   f03.bar 
5  NULL  X    cba   f04.bar 
6  NULL  NULL    ca   f05.bar 
7  NULL  x    NULL   f06.bar 
8  NULL  NULL    NULL   f07.bar.updated 
+0

感謝billinkc,但它仍然無法正常工作。僅供參考,這些都是字符串字段。 – htm11h

+0

我剝離了itemCheckDigit和itemSuf修復條件,並更新了我的三條記錄。更新:添加itemCheckDigit字段比較,並再次更新所有三個記錄。我需要弄清楚如何在itemSuffix字段中正確評估NULL的可能性。 – htm11h

+0

你能告訴我檢查字段的空值的語法是什麼?這似乎是代碼失敗的地方。 – htm11h