【问题标题】:update statement not executing更新语句未执行
【发布时间】:2011-10-01 16:06:59
【问题描述】:

我正在尝试编写一个 UPDATE 查询,该查询可以检查其中一个字段中的空值。我有三个条件,两个是强制性的,三个字段。 itemCode 和 itemCheckDigit 会一直存在,itemSuffix 可能为 Null。

可能有多个记录,其中 itemCode 和 itemCheckDigit 一起等于其他记录,itemSuffix 是 unquie 标识符,尽管 itemSuffix 为 Null 并且永远不会重复,但只会存在一个实例。

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

这是我想我想做的,但它不起作用。

【问题讨论】:

  • 显然 WHERE 子句中的某些内容限制了 UPDATE。暂时将其转换为 SELECT 并从 WHERE 中删除谓词,直到获得结果。这样你就可以隔离问题了。
  • 我想我发现了您的部分问题,但如果您想将您的描述与提供的代码同步(列不匹配),我们可以解决您的 NULL 比较问题。
  • 现在尝试您的建议,我怀疑它与 Null 有关。这是在字段中检查空值的适当语法吗?
  • 所有字段都可以为 Nullable 但只有 itemSuffix 在表中实际上可以有 null 值(无数据)。

标签: sql tsql sql-server-express sql-update


【解决方案1】:

您的问题是,您在语句中的参数周围加上了刻度线,因此在评估它时,它会从 itemCode 为“玩具”的项目表中查找内容(注意单引号)

你正在做的字符串连接是如何将参数添加到他们的动态查询中。相反,像这样去掉刻度线

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

要处理可选的搜索参数,Bill Graziano 的这篇文章非常棒: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

【讨论】:

  • 感谢 billinkc,但它仍然无法正常工作。仅供参考,这些都是字符串字段。
  • 我剥离了 itemCheckDigit 和 itemSuf 修复条件,并更新了我的三个记录。更新:添加了 itemCheckDigit 字段比较,并再次更新了所有三个记录。我需要弄清楚如何正确评估 itemSuffix 字段中为 NULL 的可能性。
  • 你能告诉我检查字段空值的语法是什么吗?这似乎是代码失败的地方。
猜你喜欢
  • 2023-03-09
  • 1970-01-01
  • 2014-07-12
  • 2020-07-23
  • 1970-01-01
  • 1970-01-01
  • 2016-03-03
  • 2018-01-05
相关资源
最近更新 更多