автоматическое приведение или что-то еще .. обновление в динамическом SQL - PullRequest
0 голосов
/ 07 февраля 2011

У меня динамический sql в хранимой процедуре:

DECLARE @sql nvarchar(1000)
            SET @sql =  'UPDATE dbo.T_CUS_TSK_TASK '+
                        'SET ' + QUOTENAME(@task_field_name) + '=@value ' +
                        'WHERE company_id=@company_id AND task_id=@task_id'
                        print(@sql)
            EXEC sp_executesql
                @sql,
                N'@company_id uniqueidentifier, @task_id bigint, @value nvarchar(50)',
                @company_id, @task_id, @value

проблема в том, что я не знаю, является ли поле, представленное @task_field_name, bigint или nvarchar, поэтому я получаю ошибку преобразования:

Error converting data type nvarchar to bigint.

Как я могу предотвратить ошибку?

Ответы [ 2 ]

1 голос
/ 07 февраля 2011

Есть только 2 случая, о которых я могу подумать, что вы получите это сообщение об ошибке.

  1. Поле task_id в базе данных на самом деле не bigint.Если это varchar и содержит что-то вроде '' (пустая строка), то предложение WHERE может завершиться ошибкой, так как столбец сравнивается с переменной bigint @ task_id.

  2. @ task_field_name установленов столбец bigint, а значение в @value равно , а не преобразуемо в bigint.Это, безусловно, ошибка программирования, потому что код TSQL на самом деле работает нормально , пока он получает правильный ввод - это то, что Мартин пытается показать вам.

Re (2), скажем, @value содержит строку 'A'.И вы попросили обновить столбец bigint с этим значением - конечно, он должен потерпеть неудачу !?Если @value содержит любое допустимое значение bigint (даже в переменной nvarchar (50)), код действительно работает .

0 голосов
/ 07 февраля 2011

Не используйте динамический SQL и не пытайтесь писать общий код UPDATE.Это не спасает вас ни разу, как вы узнали, и теперь вам нужно спросить здесь.

Либо объединить в одну ...

UPDATE
   dbo.T_CUS_TSK_TASK
SET
   bigintColumn = CASE WHEN @task_field_name = 'bigintColumn'
                                   THEN CAST(@value AS bigint) ELSE bigintColumn END
   nvarcharColumn = CASE WHEN @task_field_name = 'nvarcharColumn'
                                   THEN @value ELSE nvarcharColumn END
WHERE
   company_id = @company_id AND task_id = @task_id

...или отдельно

IF @task_field_name = 'bigintColumn'
    UPDATE
       dbo.T_CUS_TSK_TASK
    SET
       bigintColumn = CAST(@value AS bigint)
    WHERE
       company_id = @company_id AND task_id = @task_id
ELSE
    UPDATE
       dbo.T_CUS_TSK_TASK
    SET
       nvarcharColumn = @value
    WHERE
       company_id = @company_id AND task_id = @task_id

Лично у меня также не было бы общего @value в качестве параметра.Я бы выделил отдельный код или передал бы два параметра, по одному на столбец.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...