Подтвердить что ты не робот

Недопустимое имя столбца при обновлении sql-сервера после создания столбца

Кто-нибудь видит, что не так с этим кодом для SQL Server?

IF NOT EXISTS(SELECT *
              FROM   sys.columns
              WHERE  Name = 'OPT_LOCK'
                     AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK'))
  BEGIN
      ALTER TABLE REP_DSGN_SEC_GRP_LNK
        ADD OPT_LOCK NUMERIC(10, 0)

      UPDATE REP_DSGN_SEC_GRP_LNK
      SET    OPT_LOCK = 0

      ALTER TABLE REP_DSGN_SEC_GRP_LNK
        ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL
  END; 

Когда я запускаю это, я получаю:

Msg 207, уровень 16, состояние 1, строка 3
Недопустимое имя столбца "OPT_LOCK".

в команде обновления.

Спасибо.

4b9b3361

Ответ 1

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

В целом проблема заключается в проблеме синтаксического анализа/компиляции. SQL Server пытается скомпилировать все операторы в пакете перед выполнением каких-либо утверждений.

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

Если оператор ссылается на не существующий столбец в существующей таблице и на несуществующую таблицу, ошибка может быть отброшена или не удалена, прежде чем компиляция будет отложена.

Вы можете отправить его отдельными партиями (например, с помощью разделителя пакетов GO в клиентских инструментах) или выполнить его в дочерней области, которая скомпилирована отдельно с помощью EXEC или EXEC sp_executesql.

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

IF NOT EXISTS(SELECT *
              FROM   sys.columns
              WHERE  Name = 'OPT_LOCK'
                     AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK'))
  BEGIN
      ALTER TABLE REP_DSGN_SEC_GRP_LNK
        ADD OPT_LOCK NUMERIC(10, 0)

      EXEC('UPDATE REP_DSGN_SEC_GRP_LNK SET OPT_LOCK = 0');

      ALTER TABLE REP_DSGN_SEC_GRP_LNK
        ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL
  END; 

Ответ 2

Для вашей информации вы можете заменить IF NOT EXISTS на функцию COL_LENGTH. Он принимает два параметра,

  • Имя таблицы и

  • Колонка, которую вы ищете

Если столбец найден, он возвращает диапазон типа данных столбца Ex: Int (4 байта), если он не найден, он возвращает NULL.

Итак, вы можете использовать это следующим образом, а также объединить 3 выражения в один.

IF (SELECT COL_LENGTH('REP_DSGN_SEC_GRP_LNK','OPT_LOCK')) IS NULL

BEGIN

    ALTER TABLE REP_DSGN_SEC_GRP_LNK
    ADD OPT_LOCK NUMERIC(10, 0) NOT NULL DEFAULT 0

END;

Делает это проще.