инструкция update не выполняется

#sql #tsql #sql-server-express #sql-update

#sql #tsql #sql-server-express #sql-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); 
  

Это то, что, я думаю, я хотел бы сделать, но это не работает.

Комментарии:

1. Очевидно, что-то в вашем предложении WHERE ограничивает ОБНОВЛЕНИЕ. Временно преобразуйте его в SELECT и удаляйте предикаты из WHERE, пока не получите результаты. Тогда вы изолируете проблему.

2. Я думаю, что я определил часть вашей проблемы, но если вы хотите синхронизировать свое описание с предоставленным кодом (столбцы не совпадают), мы можем решить ваши проблемы с нулевым сравнением.

3. Пробую ваше предложение сейчас, у меня есть подозрение, что это связано с Null . Является ли это подходящим синтаксисом для проверки наличия нулевого значения в поле?

4. Все поля обнуляются, но только itemSuffix может фактически иметь нулевое значение в таблице (нет данных).

Ответ №1:

Ваша проблема в том, что вы оборачиваете галочки вокруг своих параметров в своем заявлении, поэтому при его оценке он ищет данные из таблицы item, где ItemCode является «игрушкой» (обратите внимание на одинарные кавычки)

Конкатенация строк, которую вы выполняете, заключается в том, как можно было бы, плохо, добавлять параметры к своим динамическим запросам. Вместо этого уберите галочки следующим образом

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

Для обработки необязательных параметров поиска превосходна эта статья Билла Грациано: использование динамического SQL в хранимых процедурах. Я считаю, что это обеспечивает хороший баланс между тем, чтобы избегать перекомпиляции запросов при установке параметра перекомпиляции и избегать сканирования таблиц.

Пожалуйста, наслаждайтесь этим кодом. Он создает временную таблицу для имитации вашей фактической таблицы элементов и загружает в нее 8 строк данных. Я объявляю некоторые параметры, которые вам, скорее всего, не понадобятся, поскольку ado.net библиотека сделает часть этого волшебства за вас.

На основе значений, предоставленных для первых 3 параметров, вы получите эквивалентное соответствие строке в таблице и обновите значение filename. В моем примере вы увидите, что в строке all NULL имя файла будет изменено с f07.bar на f07.bar.updated.

Инструкция print не требуется, но я вставил ее туда, чтобы вы могли видеть запрос, который построен как помощь в понимании шаблона.

 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
  

Комментарии:

1. Спасибо billinkc, но он все еще не работает. К вашему сведению, это все строковые поля.

2. Я удалил условие исправления itemCheckDigit и itemSuf, и мои три записи обновлены. ОБНОВЛЕНИЕ: добавлено сравнение полей itemCheckDigit, и снова все три записи обновлены. Мне нужно выяснить, как правильно оценить возможность NULL в поле itemSuffix.

3. Можете ли вы сказать мне, какой синтаксис используется для проверки нулевого значения поля? Похоже, именно здесь происходит сбой кода.