Оценка кода SQL останавливает допустимую транзакцию - PullRequest
0 голосов
/ 07 мая 2019

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

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

IF EXISTS (
SELECT * 
FROM   sys.columns 
WHERE  object_id = OBJECT_ID(N'[Central].[Core.Report].[ReportLessonComp]') 
       AND name = 'Name')
       and 
       EXISTS (
SELECT * 
FROM   sys.columns 
WHERE  object_id = OBJECT_ID(N'[Central].[Core.Report].[ReportLessonComp]') 
       AND name = 'Code')
BEGIN
UPDATE
    [Central].[Core.Report].[ReportLessonComp]
SET
    CompetencyId = rc.Id
FROM
    [Central].[Core.Report].[ReportLessonComp] rlc
INNER JOIN
    [Core.Lookup].ReportCompetency rc
ON 
    rc.Code = rlc.Code and rc.Name = rlc.Name

ALTER TABLE [Central].[Core.Report].[ReportLessonComp] DROP COLUMN CODE
ALTER TABLE [Central].[Core.Report].[ReportLessonComp] DROP COLUMN [Name]
ALTER TABLE [Central].[Core.Report].[ReportLessonComp] DROP COLUMN [Description]

END
GO

При запуске проверок if существует \ не существует, а затем выберите getdate (), это прекрасно работает и дает ожидаемый результат.

Однако, когда я запускаю блок кода выше, я получаю сообщение об ошибке

Сообщение 207, Уровень 16, Состояние 1, Строка 23

Неверное имя столбца «Код».

Сообщение 207, Уровень 16, Состояние 1, Строка 23

Недопустимое имя столбца 'Имя'.

Этот сценарий является частью более крупного сценария обновления ииспользуется в системном вызове RoundHouse https://github.com/chucknorris/roundhouse, который является системой, выбранной компанией.

До проверки, если существует,

IF (SELECT COUNT(1) FROM sys.columns 
WHERE OBJECT_ID = OBJECT_ID('[Central].[Core.Report].[ReportLessonComp]')
AND Name in ('Name','Code')) = 2  

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

Что я могу сделать, чтобы не допустить сбоя сценариев обновления?

РЕДАКТИРОВАТЬ. Причина, по которой я связываю поля varchar, заключается также и в том, что предыдущий разработчик не создавал связи между таблицами, а просто вставлял строки в таблицы, а не связывал их по идентификатору, вызывая возможность несвязанных \ несогласованныхданные.

Редактирование таблицы до этого создает новый столбец id, и этот скрипт получает значение и отбрасывает столбцы, которые больше не нужны

1 Ответ

1 голос
/ 07 мая 2019

SQL Server будет выполнять синтаксический анализ всего оператора до его выполнения, поэтому проверка существования не защитит вас от анализа обновления.Если столбец уже удален, это делает оператор недействительным, и вы получаете ошибку разбора.Оператор обновления должен выполняться как динамический SQL, в основном sp_execute, чтобы varchar обновления не анализировался напрямую.

Для SQL Server 2016 и более поздних версий столбец удаления также можно защитить немного больше:

ALTER TABLE [Central].[Core.Report].[ReportLessonComp] DROP COLUMN IF EXISTS CODE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...