Глобальные переменные с GO - PullRequest
22 голосов
/ 23 марта 2011

Я пытаюсь пакетировать некоторые сценарии 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
...

объявления выходят за рамки ... то есть когда я запускаю этопоследующие пакетные сценарии не находят эти объявления.Есть ли способ сохранить их глобальными для всех пакетных сценариев, которые используют или задают эти переменные для использования?

Ответы [ 5 ]

21 голосов
/ 23 марта 2011

Временные таблицы выживают go s:

create table #vars (someVar1 varchar(10), someVar2 int)
insert #vars values ('abc',123)

Получить значение:

select someVar1 from #vars

Заданное значение

update #vars set someVar1 = 'def'

Временные таблицы специфичны для вашего соединения, поэтому они не более глобальны, чем должны быть.

10 голосов
/ 07 апреля 2014

Вы можете объявить переменные сценариев, которые могут быть явно определены с помощью команды 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

4 голосов
/ 23 марта 2011

Вам может не потребоваться использование пакетов, и в этом случае вы можете заставить свои переменные выживать в течение очень долгого времени. Я не уверен, что это лучшая практика, но, например, объявление функции обычно должно быть единственным оператором в пакете, например так:

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

Это действительно зависит от сложности вашего скрипта, от того, хотите ли вы сделать это, поскольку он может стать немного запутанным, и вы потеряете подсветку синтаксиса, как только все будет в гигантской строке:)

4 голосов
/ 23 марта 2011

Глобальной переменной не существует, но вы можете сделать что-то вроде этого: Ссылка

Пример использования:

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.

2 голосов
/ 23 марта 2011

Переменные выходят из области видимости, потому что оператор GO сигнализирует об окончании пакета. Раздел документации Microsoft Переменные Transact-SQL имеет следующий пример:

Объем переменная длится с того момента, как это объявлено до конца партии или хранимая процедура, в которой это объявлен. Например, следующее скрипт генерирует синтаксическую ошибку потому что переменная объявлена ​​в одна партия и ссылка на другую:

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;

Я думаю, что вы хотите создать временную таблицу для хранения ваших "глобальных" переменных. Посмотрите ответ Andomar для примера того, как это сделать. У него есть одна переменная на строку. Я также вижу временные таблицы, в которых есть столбец для каждой требуемой глобальной переменной, и в таблицу вставляется только одна строка. Это позволяет каждой переменной иметь свой тип данных.

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