Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Скрипт обновления БД не видит созданные колонки  [new]
SolidSnake
Member

Откуда:
Сообщений: 98
Добрый день!

Искал, но не нашел тут такого же вопроса.
Мне периодически надо вносить изменения в БД.
В процессе разработки ПО, все изменения в БД оформляю в виде TSQL кода.
К релизу, у меня получается скрипт, в котором последовательно собраны изменения, которые необходимо применить.

Не знаю почему, то что работает кусками, не работает при разовом исполнении.
Пишет "Недопустимое имя столбца "created_by_employee"", т.е. скрипт не видит столбец, который создается парой строк выше.
Если выполнить кусками 2 запроса по очереди, то все ОК.

Если я не ошибаюсь, нужно выключить какие-то проверки на момент выполнения скрипта?

BEGIN TRANSACTION
BEGIN TRY

	DECLARE @db_version NVARCHAR(1000);
	DECLARE @ssc_min_version NVARCHAR(1000);

	-- Получим версию базы данных
	SET @db_version = (SELECT [MetaInfo].[value] FROM [MetaInfo] WHERE [MetaInfo].[metadata] = N'db_version');

	IF (@db_version = N'7') -- Обновление базы данных до версии 8 (0.8.3)
	BEGIN

		-- Установка метаданных новой версии базы данных и минимальной версии программы
		SET @db_version = N'8';
		SET @ssc_min_version = '0.8.3';

		-- Добавление колонки [created_by_customer] и [created_by_employee] в [Requests]
		ALTER TABLE [Requests] 
		ADD	[created_by_customer] bit NOT NULL DEFAULT (0),
			[created_by_employee] bit NOT NULL DEFAULT (0),
			[created_by_operator] bit NOT NULL DEFAULT (0),
			[created_by_administrator] bit NOT NULL DEFAULT (0)

		-- Определение ролей пользователей и установка признака в обращения
		UPDATE [Requests]
			SET [created_by_employee] = 
				CASE WHEN 'CC3F32FD-E4CE-49E3-81C1-05639C6CB658' IN (
					SELECT [UsersRoles].[role_id] 
					FROM [UsersRoles] 
					WHERE [UsersRoles].[user_id] = [Requests].[user_id] AND [UsersRoles].[product_id] = [Requests].[product_id]) THEN
				CAST(1 AS BIT) ELSE CAST(0 AS BIT) END

		-- Запись метаданных
		UPDATE [MetaInfo] SET [MetaInfo].[value] = @db_version WHERE [MetaInfo].[metadata] = N'db_version';
		UPDATE [MetaInfo] SET [MetaInfo].[value] = @ssc_min_version WHERE [MetaInfo].[metadata] = N'ssc_min_version';

	END

COMMIT TRANSACTION;
END TRY
BEGIN CATCH
	-- Перехват ошибки, отмена транзакции, возврат ошибки
	ROLLBACK TRANSACTION;
	DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;
	SET @ErrorMessage = ERROR_MESSAGE();
    SET @ErrorSeverity = ERROR_SEVERITY();
    SET @ErrorState = ERROR_STATE();
	RAISERROR( @ErrorMessage, @ErrorSeverity, @ErrorState );
END CATCH
8 авг 14, 14:14    [16417404]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
Glory
Member

Откуда:
Сообщений: 104751
SolidSnake
Не знаю почему, то что работает кусками, не работает при разовом исполнении.

Rules for Using Batches
The following rules apply to using batches:

- CREATE DEFAULT, CREATE FUNCTION, CREATE PROCEDURE, CREATE RULE, CREATE SCHEMA, CREATE TRIGGER, and CREATE VIEW statements cannot be combined with other statements in a batch. The CREATE statement must start the batch. All other statements that follow in that batch will be interpreted as part of the definition of the first CREATE statement.

- A table cannot be changed and then the new columns referenced in the same batch.

- If an EXECUTE statement is the first statement in a batch, the EXECUTE keyword is not required. The EXECUTE keyword is required if the EXECUTE statement is not the first statement in the batch.
8 авг 14, 14:16    [16417414]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
Konst_One
Member

Откуда:
Сообщений: 11621
так не выйдет у вас

GO не хватает, но обработку ошибок в таком виде не получите
8 авг 14, 14:16    [16417420]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
invm
Member

Откуда: Москва
Сообщений: 9835
		UPDATE [Requests]
			SET [created_by_employee] = 
				CASE WHEN 'CC3F32FD-E4CE-49E3-81C1-05639C6CB658' IN (
					SELECT [UsersRoles].[role_id] 
					FROM [UsersRoles] 
					WHERE [UsersRoles].[user_id] = [Requests].[user_id] AND [UsersRoles].[product_id] = [Requests].[product_id]) THEN
				CAST(1 AS BIT) ELSE CAST(0 AS BIT) END
Замените на
		exec('UPDATE [Requests]
			SET [created_by_employee] = 
				CASE WHEN ''CC3F32FD-E4CE-49E3-81C1-05639C6CB658'' IN (
					SELECT [UsersRoles].[role_id] 
					FROM [UsersRoles] 
					WHERE [UsersRoles].[user_id] = [Requests].[user_id] AND [UsersRoles].[product_id] = [Requests].[product_id]) THEN
				CAST(1 AS BIT) ELSE CAST(0 AS BIT) END')
8 авг 14, 14:21    [16417467]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
SolidSnake
Member

Откуда:
Сообщений: 98
Спасибо за ответы)
Интересно, а как правильнее поступить?
Избавится от попытки, добавить GO и как-то откатывать транзакцию автоматически при ошибке?
Или использовать вариант с exec?
8 авг 14, 14:28    [16417533]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
Konst_One
Member

Откуда:
Сообщений: 11621
лучше в разных batch-ах выполнять DDL и DML
8 авг 14, 14:31    [16417557]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
SolidSnake
Спасибо за ответы)
Интересно, а как правильнее поступить?
Избавится от попытки, добавить GO и как-то откатывать транзакцию автоматически при ошибке?
Или использовать вариант с exec?
Сервер не знает никакого GO!
В каком приложении выполняете скрипт?
8 авг 14, 14:32    [16417564]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
SolidSnake
Member

Откуда:
Сообщений: 98
Сейчас выполняю скрипт в SQL менеджмент студии.
Потом скрипт будет посылаться через FireDac в MS SQL.
8 авг 14, 15:30    [16418092]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
Glory
Member

Откуда:
Сообщений: 104751
SolidSnake
Сейчас выполняю скрипт в SQL менеджмент студии.
Потом скрипт будет посылаться через FireDac в MS SQL.

GO - это не команда TSQL
GO - это разделитель пакетов в утилитах MS. Причем раздеитель этот можно настраивать в этих утилитах.
8 авг 14, 15:34    [16418147]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
SolidSnake
Member

Откуда:
Сообщений: 98
Konst_One
лучше в разных batch-ах выполнять DDL и DML

В рамках одной транзакции, верно?
8 авг 14, 16:24    [16418602]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
SolidSnake
Member

Откуда:
Сообщений: 98
Если я просто уберу TRY, оставлю транзакцию, то при ошибке транзакция не закрепится же?
8 авг 14, 16:26    [16418620]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
invm
Member

Откуда: Москва
Сообщений: 9835
SolidSnake
В рамках одной транзакции, верно?
Если нужно в рамках одной транзакции - делайте все в одном пакете.
8 авг 14, 16:30    [16418647]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
Konst_One
Member

Откуда:
Сообщений: 11621
SolidSnake
Konst_One
лучше в разных batch-ах выполнять DDL и DML

В рамках одной транзакции, верно?


Batches

Batch - это набор операторов TSQL, передаваемых на выпонение и выполняющихся вместе, как одно целое. Batch компилируется целиком и оканчивается специальным символом-сигналом конца (go). Все последовательности операторов TSQL, набираемые в ISQL/w или в Enterprise Manager интерпретируются именно как batch'и (интересно то, что при выделении некоторой части текста в окне выполняться будет именно она)
Пример



Несколько SELECT в одном batch'е
  SELECT COUNT(*) FROM titles
  SELECT COUNT(*) FROM authors


https://www.sql.ru/docs/mssql/tsql_ref/
8 авг 14, 16:30    [16418649]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4896
Konst_One,

если нужно DDL и DML в одной транзакции, то надо оборачивать EXEC('....')

Тогда в первом EXEC добавить колонки, во втором исполнить запрос с их использованием и не будет ошибки.
8 авг 14, 19:08    [16419360]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
invm
Member

Откуда: Москва
Сообщений: 9835
a_voronin
Тогда в первом EXEC добавить колонки
Зачем DDL заворачивать в динамику?
8 авг 14, 20:36    [16419582]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт обновления БД не видит созданные колонки  [new]
Konst_One
Member

Откуда:
Сообщений: 11621
a_voronin
Konst_One,

если нужно DDL и DML в одной транзакции, то надо оборачивать EXEC('....')

Тогда в первом EXEC добавить колонки, во втором исполнить запрос с их использованием и не будет ошибки.



мне это ни к чему, вы лучше напишите ТС
8 авг 14, 20:57    [16419628]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить