Есть ли способ сохранить переменную на ходу?
Declare @bob as varchar(50);
Set @bob = 'SweetDB';
GO
USE @bob --- see note below
GO
INSERT INTO @bob.[dbo].[ProjectVersion] ([DB_Name], [Script]) VALUES (@bob,'1.2')
См. Этот вопрос SO для строки «USE @bob».
Ответы:
В
go
используется для разделения кода на отдельные пакеты. Если это именно то, что вы хотите сделать, вам следует использовать его, но это означает, что пакеты фактически разделены, и вы не можете совместно использовать переменные между ними.В вашем случае решение простое; вы можете просто удалить
go
операторы, они не нужны в этом коде.Боковое примечание: вы не можете использовать переменную в
use
инструкции, это должно быть имя базы данных.источник
go
команда используется для разделения кода на отдельные пакеты. Если это то, что вы хотите сделать, вам следует использовать это, но это означает, что пакеты фактически разделены, и вы не можете совместно использовать переменные между ними.Используйте временную таблицу:
CREATE TABLE #variables ( VarName VARCHAR(20) PRIMARY KEY, Value VARCHAR(255) ) GO Insert into #variables Select 'Bob', 'SweetDB' GO Select Value From #variables Where VarName = 'Bob' GO DROP TABLE #variables go
источник
Я предпочитаю этот ответ от этого вопроса Глобальные переменные с GO
Который имеет дополнительное преимущество в том, что вы можете делать то, что вы изначально хотели делать.
Предостережение заключается в том, что вам нужно включить режим SQLCMD (в разделе Query-> SQLCMD) или включить его по умолчанию для всех окон запросов (Инструменты-> Параметры, затем Результаты запроса-> По умолчанию открывать новые запросы в режиме SQLCMD)
Затем вы можете использовать следующий тип кода (полностью скопированный из того же ответа Оскара Э. Фракседаса Тормо )
--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
источник
Если вы используете SQL Server, вы можете настроить глобальные переменные для целых сценариев, например:
и использовать позже в скрипте как:
Убедитесь, что режим SQLCMD включен в Server Managment Studi, вы можете сделать это через верхнее меню. Нажмите «Запрос» и включите режим SQLCMD.
Подробнее по теме можно найти здесь: Документация MS
источник
Не уверен, что это поможет
declare @s varchar(50) set @s='Northwind' declare @t nvarchar(100) set @t = 'select * from ' + @s + '.[dbo].[Customers]' execute sp_executesql @t
источник
Временные таблицы сохраняются в операторах GO, поэтому ...
SELECT 'value1' as variable1, 'mydatabasename' as DbName INTO #TMP -- get a variable from the temp table DECLARE @dbName VARCHAR(10) = (select top 1 #TMP.DbName from #TMP) EXEC ('USE ' + @dbName) GO -- get another variable from the temp table DECLARE @value1 VARCHAR(10) = (select top 1 #TMP.variable1 from #TMP) DROP TABLE #TMP
Это некрасиво, но работает
источник
Создайте свои собственные хранимые процедуры, которые сохраняют / загружают во временную таблицу.
MyVariableSave -- Saves variable to temporary table. MyVariableLoad -- Loads variable from temporary table.
Тогда вы можете использовать это:
print('Test stored procedures for load/save of variables across GO statements:') declare @MyVariable int = 42 exec dbo.MyVariableSave @Name = 'test', @Value=@MyVariable print(' - Set @MyVariable = ' + CAST(@MyVariable AS VARCHAR(100))) print(' - GO statement resets all variables') GO -- This resets all variables including @MyVariable declare @MyVariable int exec dbo.MyVariableLoad 'test', @MyVariable output print(' - Get @MyVariable = ' + CAST(@MyVariable AS VARCHAR(100)))
Вывод:
Test stored procedures for load/save of variables across GO statements: - Set @MyVariable = 42 - GO statement resets all variables - Get @MyVariable = 42
Вы также можете использовать их:
exec dbo.MyVariableList -- Lists all variables in the temporary table. exec dbo.MyVariableDeleteAll -- Deletes all variables in the temporary table.
Выход
exec dbo.MyVariableList
:Оказывается, возможность перечислить все переменные в таблице на самом деле весьма полезна. Таким образом, даже если вы не загрузите переменную позже, это отлично подходит для целей отладки, чтобы увидеть все в одном месте.
Здесь используется временная таблица с
##
префиксом, так что этого достаточно, чтобы выжить после оператора GO. Он предназначен для использования в одном скрипте.И хранимые процедуры:
-- Stored procedure to save a variable to a temp table. CREATE OR ALTER PROCEDURE MyVariableSave @Name varchar(255), @Value varchar(MAX) WITH EXECUTE AS CALLER AS BEGIN SET NOCOUNT ON IF NOT EXISTS (select TOP 1 * from tempdb.sys.objects where name = '##VariableLoadSave') BEGIN DROP TABLE IF EXISTS ##VariableLoadSave CREATE TABLE ##VariableLoadSave ( Name varchar(255), Value varchar(MAX) ) END UPDATE ##VariableLoadSave SET Value=@Value WHERE Name=@Name IF @@ROWCOUNT = 0 INSERT INTO ##VariableLoadSave SELECT @Name, @Value END GO -- Stored procedure to load a variable from a temp table. CREATE OR ALTER PROCEDURE MyVariableLoad @Name varchar(255), @Value varchar(MAX) OUT WITH EXECUTE AS CALLER AS BEGIN IF EXISTS (select TOP 1 * from tempdb.sys.objects where name = '##VariableLoadSave') BEGIN IF NOT EXISTS(SELECT TOP 1 * FROM ##VariableLoadSave WHERE Name=@Name) BEGIN declare @ErrorMessage1 as varchar(200) = 'Error: cannot find saved variable to load: ' + @Name raiserror(@ErrorMessage1, 20, -1) with log END SELECT @Value=CAST(Value AS varchar(MAX)) FROM ##VariableLoadSave WHERE Name=@Name END ELSE BEGIN declare @ErrorMessage2 as varchar(200) = 'Error: cannot find saved variable to load: ' + @Name raiserror(@ErrorMessage2, 20, -1) with log END END GO -- Stored procedure to list all saved variables. CREATE OR ALTER PROCEDURE MyVariableList WITH EXECUTE AS CALLER AS BEGIN IF EXISTS (select TOP 1 * from tempdb.sys.objects where name = '##VariableLoadSave') BEGIN SELECT * FROM ##VariableLoadSave ORDER BY Name END END GO -- Stored procedure to delete all saved variables. CREATE OR ALTER PROCEDURE MyVariableDeleteAll WITH EXECUTE AS CALLER AS BEGIN DROP TABLE IF EXISTS ##VariableLoadSave CREATE TABLE ##VariableLoadSave ( Name varchar(255), Value varchar(MAX) ) END
источник
Если вам просто нужно двоичное да / нет (например, если столбец существует), вы можете использовать его
SET NOEXEC ON
для отключения выполнения операторов.SET NOEXEC ON
работает по GO (по партиям). Но не забудьте снова включить EXEC с помощьюSET NOEXEC OFF
в конце скрипта.IF COL_LENGTH('StuffTable', 'EnableGA') IS NOT NULL SET NOEXEC ON -- script will not do anything when column already exists ALTER TABLE dbo.StuffTable ADD EnableGA BIT NOT NULL CONSTRAINT DF_StuffTable_EnableGA DEFAULT(0) ALTER TABLE dbo.StuffTable SET (LOCK_ESCALATION = TABLE) GO UPDATE dbo.StuffTable SET EnableGA = 1 WHERE StuffUrl IS NOT NULL GO SET NOEXEC OFF
Это компилирует операторы, но не выполняет их. Так что вы все равно будете получать «ошибки компиляции», если будете ссылаться на несуществующую схему. Таким образом, он работает, чтобы «выключить» второй запуск скрипта (что я делаю), но не работает, чтобы отключить части скрипта при первом запуске, потому что вы все равно будете получать ошибки компиляции, если будете ссылаться на столбцы или таблицы, которые не пока не существует.
источник
Вы можете использовать NOEXEC, выполнив следующие шаги:
Создать таблицу
#temp_procedure_version(procedure_version varchar(5),pointer varchar(20))
вставить версии процедуры и указатель на версию во временную таблицу
#temp_procedure_version
--example указатель на версию_процедуры
вставить в
temp_procedure_version
значения (1.0, 'первая версия')вставить в
temp_procedure_version
значения (2.0, 'final version')затем получить версию процедуры, вы можете использовать условие where, как в следующем заявлении
Выберите
@ProcedureVersion=ProcedureVersion
из#temp_procedure_version
гдеpointer='first version'
IF (@ProcedureVersion='1.0') BEGIN SET NOEXEC OFF --code execution on END ELSE BEGIN SET NOEXEC ON --code execution off END
- вставить сюда процедуру версии 1.0
Создайте процедуру версии 1.0 как .....
SET NOEXEC OFF -- execution is ON
Выберите
@ProcedureVersion=ProcedureVersion
из#temp_procedure_version
где указателя = «окончательного варианта»IF (@ProcedureVersion='2.0') BEGIN SET NOEXEC OFF --code execution on END ELSE BEGIN SET NOEXEC ON --code execution off END
Создайте процедуру версии 2.0 как .....
SET NOEXEC OFF -- execution is ON
- сбросить временную таблицу
Удалить таблицу
#temp_procedure_version
источник