Глобальные переменные с GO
Я пытаюсь выполнить некоторые SQL-скрипты. В верхней части я объявил некоторые переменные, которые я считаю глобальными в смысле термина
Итак:
DECLARE @someVar1
DECLARE @someVar2
...etc.
GO
Some batch of SQL here that sets @someVar1 and @SomeVar2 to a value and uses it in the SQL statement
GO
Some batch of SQL here that sets @someVar1 and @SomeVar2 to a value and uses it in the SQL statement
GO
...
объявления выходят за пределы области видимости... что означает, что когда я запускаю это, последующие командные скрипты не находят эти объявления. Есть ли способ сохранить их глобальными для всех пакетных скриптов, которые используют или устанавливают эти переменные для использования?
Ответы
Ответ 1
Временные таблицы выживают go
's:
create table #vars (someVar1 varchar(10), someVar2 int)
insert #vars values ('abc',123)
Получить значение:
select someVar1 from #vars
Установленное значение
update #vars set someVar1 = 'def'
Временные таблицы специфичны для вашего соединения, поэтому они не являются более глобальными, чем они должны быть.
Ответ 2
Вы можете объявить переменные Scripting Variables, которые могут быть определены явно с помощью команды setvar и не выходить за пределы области действия в инструкции GO.
например.
--Declare the variable
:setvar MYDATABASE master
--Use the variable
USE $(MYDATABASE);
SELECT * FROM [dbo].[refresh_indexes]
GO
--Use again after a GO
SELECT * from $(MYDATABASE).[dbo].[refresh_indexes];
GO
Для получения дополнительной информации перейдите по ссылке: http://technet.microsoft.com/en-us/library/ms188714.aspx
Ответ 3
Нет такой вещи, как глобальная переменная, но вы можете сделать что-то вроде этого: Ссылка
Пример использования:
EXEC sp_SetGlobalVariableValue 'Test1', 'test1'
EXEC sp_SetGlobalVariableValue 'Test2', 'test2'
GO
EXEC sp_GetGlobalVariableValue 'Test1'
EXEC sp_GetGlobalVariableValue 'Test2'
GO
EXEC sp_GetGlobalVariableValue 'Test1'
EXEC sp_GetGlobalVariableValue 'Test2'
GO
Используя хранимые процедуры, упомянутые в ссылке выше, я смог установить глобальные переменные и провести их между GO.
Ответ 4
Вам могут не потребоваться использование партий, и в этом случае вы можете заставить переменные выжить в течение очень долгого времени. Я не уверен, что это лучшая практика, но, например, объявление функции обычно должно быть единственным оператором в пакете, например:
Declare @batch_scope_var INT
GO --This is required
CREATE FUNCTION dbo.Half(@function_scope_var int)
RETURNS int
WITH EXECUTE AS CALLER
AS
BEGIN
RETURN @function_scope_var/2
END
GO --This is required
SET @batch_scope_var = 4 --Bugger, this is now out of scope and won't execute!
print dbo.Half(@batch_scope_var)
GO
Однако вы можете перезаписать его с помощью * sp_executesql * и избежать всех таких партий:
Declare @batch_scope_var INT
execute dbo.sp_executesql @statement = N'
CREATE FUNCTION dbo.Half(@function_scope_var int)
RETURNS int
WITH EXECUTE AS CALLER
AS
BEGIN
RETURN @function_scope_var/2
END
'
SET @batch_scope_var = 4
print dbo.Half(@batch_scope_var)
GO
На самом деле это зависит от сложности вашего script относительно того, хотите ли вы это сделать, поскольку он может стать немного беспорядочным, и вы потеряете выделение синтаксиса, как только все будет в гигантской строке:)
Ответ 5
Переменные выходят за рамки, потому что оператор GO сигнализирует о завершении партии. В разделе документации Microsoft Transact-SQL Variables приведен пример:
Объем переменная длится с той точки, в которой она находится объявляется до конца партии или хранимая процедура, в которой она объявлен. Например, следующее script генерирует синтаксическую ошибку потому что переменная объявлена в одна партия и ссылка на другую:
USE AdventureWorks2008R2;
GO
DECLARE @MyVariable int;
SET @MyVariable = 1;
-- Terminate the batch by using the GO keyword.
GO
-- @MyVariable has gone out of scope and no longer exists.
-- This SELECT statement generates a syntax error because it is
-- no longer legal to reference @MyVariable.
SELECT BusinessEntityID, NationalIDNumber, JobTitle
FROM HumanResources.Employee
WHERE BusinessEntityID = @MyVariable;
Я думаю, что вы хотите создать временную таблицу для хранения ваших "глобальных" переменных. См. Комментарий Андомара для примера того, как это сделать. Он получил одну переменную за строку. Я также вижу временные таблицы, которые имеют столбец для каждой глобальной переменной, и только одна строка вставляется в таблицу. Это позволяет каждой переменной иметь другой тип данных.