Есть ли способ сохранить переменную в пути?
Есть ли способ сохранить переменную на ходу?
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')
См. этот qaru.site/info/107211/... вопрос для строки "USE @bob".
Ответы
Ответ 1
Команда go
используется для разделения кода на отдельные партии. Если это именно то, что вы хотите сделать, то вы должны использовать его, но это означает, что партии фактически разделены, и вы не можете делиться между ними переменными.
В вашем случае решение прост; вы можете просто удалить операторы go
, они не нужны в этом коде.
Примечание: вы не можете использовать переменную в инструкции use
, она должна быть именем базы данных.
Ответ 2
Используйте временную таблицу:
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
Ответ 3
Я предпочитаю этот ответ на этот вопрос
Глобальные переменные с GO
У кого есть дополнительное преимущество, чтобы иметь возможность делать то, что вы изначально хотели сделать.
Предостережение заключается в том, что вам нужно включить режим SQLCMD (в Query- > SQLCMD) или включить его по умолчанию для всех окон запросов (Tools- > Options, а затем Query Results- > By Default, открыть новые запросы в режиме SQLCMD )
Затем вы можете использовать следующий тип кода (полностью сорванный с того же ответа Oscar E. Fraxedas Tormo)
--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
Ответ 4
вы можете использовать динамический sql, просто будьте в курсе рисков безопасности с этим (не на 100% уверены в правильном syntex)
объявить @bob nvarchar (50)
declare @sql nvarchar(max)
set @bob='SweetDB'
set @sql = 'Use ' + @bob
execute sp_executesql @sql
Ответ 5
Не уверен, если это помогает
declare @s varchar(50)
set @s='Northwind'
declare @t nvarchar(100)
set @t = 'select * from ' + @s + '.[dbo].[Customers]'
execute sp_executesql @t
Ответ 6
Если вы используете SQL Server, вы можете настроить глобальные переменные для всех сценариев, например:
:setvar sourceDB "lalalallalal"
и использовать позже в script как:
$(sourceDB)
Убедитесь, что режим SQLCMD включен в Server Managment Studi, вы можете сделать это через верхнее меню. Нажмите "Запрос" и включите режим SQLCMD.
Подробнее о теме можно узнать здесь:
Документация по MS
Ответ 7
Таблицы Temp сохраняются над операторами 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
Это не очень, но работает
Ответ 8
Создайте свои собственные хранимые процедуры, которые сохраняют/загружают во временную таблицу.
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', @[email protected]
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
:
Name Value
test 42
Оказывается, что возможность перечисления всех переменных в таблице на самом деле весьма полезна. Поэтому, даже если вы не загружаете переменную позже, это отлично подходит для целей отладки, чтобы увидеть все в одном месте.
При этом используется временная таблица с префиксом ##
, так что этого достаточно, чтобы выдержать оператор 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 [email protected] WHERE [email protected]
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 [email protected])
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 [email protected]
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
Ответ 9
Если вам просто нужен двоичный файл yes/no (например, если столбец существует), вы можете использовать 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
Это компилирует операторы, но не выполняет их. Таким образом, вы все равно получите "ошибки компиляции", если будете ссылаться на несуществующую схему. Так что он работает, чтобы "отключить" скрипт 2-го запуска (что я делаю), но не работает, чтобы отключить части скрипта при 1-м запуске, потому что вы все равно получите ошибки компиляции, если ссылаетесь на столбцы или таблицы, которые не работают. еще не существует