Как обновить таблицу и игнорировать вычисляемый столбец, если он вычисляется, но обновить его, если он не вычислен - PullRequest
0 голосов
/ 10 июня 2019

У меня есть разные версии баз данных SQL Server:

  • в DB 1, столбец «IsReadOnly» - это вычисляемый столбец
  • в DB 2, столбец «IsReadOnly» - этоНЕ вычисляемый столбец

Мне нужно создать стандартный скрипт, который будет работать на обеих версиях:

IF EXISTS (SELECT 1 FROM sys.columns 
           WHERE Name = N'IsReadOnly'
             AND Object_ID = OBJECT_ID(N'dbo.TableA')
             AND is_computed = 0) 
BEGIN
    UPDATE TableA   
    SET IsReadOnly = @IsReadOnly    
    WHERE Id = @ID 
END

При выполнении вышеописанного он работает на версии, где is_computed = 0Но при запуске в версии, где is_computed = 1, я получаю:

Сообщение 271, уровень 16, состояние 1, строка 322
Столбец "IsReadOnly" не может быть изменен, поскольку онвычисляемый столбец или является результатом оператора UNION

Любая помощь очень ценится.Спасибо

1 Ответ

3 голосов
/ 10 июня 2019

Это проблема времени компиляции и времени исполнения. Ошибка происходит во время компиляции в базе данных, где значение не может быть обновлено.

Вы можете обойти это, используя динамический SQL:

IF EXISTS( SELECT 1 FROM sys.columns 
           WHERE Name = N'IsReadOnly'
           AND Object_ID = Object_ID(N'dbo.TableA')
           AND is_computed = 0          
          ) 
BEGIN
    EXEC sp_execute_sql N'
Update TableA    
   Set IsReadOnly = @IsReadOnly     
   Where Id = @ID',
                       N'@IsReadOnly int, @ID int',  -- guessing at the types
                       @IsReadOnly=@IsReadOnly, @ID=@ID;
END

Однако более простым методом может быть блок TRY / CATCH:

BEGIN TRY
    Update TableA    
       Set IsReadOnly = @IsReadOnly     
       Where Id = @ID ;
END TRY
BEGIN CATCH
    -- Check for the particular error and do something when that occurs
END CATCH;
...