Pergunta

Existe uma maneira de manter uma variável através de uma vez?

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')

Veja este SO pergunta para a linha 'USE @bob'.

Foi útil?

Solução

O comando go é usado para dividir código em lotes separados. Se isso é exatamente o que você quer fazer, então você deve usá-lo, mas isso significa que os lotes são realmente separado, e você não pode variáveis ??partilhar entre eles.

No seu caso, a solução é simples; você pode simplesmente remover as instruções go, eles não são necessários nesse código.

Nota lateral:. Você não pode usar uma variável em um comunicado use, ele tem de ser o nome de um banco de dados

Outras dicas

Use uma tabela temporária:

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

Eu prefiro o esta resposta desta questão variáveis ??globais com GO

O que tem a vantagem adicional de ser capaz de fazer o que você queria, a fazer tão bem.

A ressalva é que você precisa para ativar o modo SQLCMD (sob query-> SQLCMD) ou ligá-lo por padrão para todas as janelas de consulta (Ferramentas-> Opções, em seguida, consulta Resultados-> Por padrão, abrem novas consultas no modo SQLCMD )

Em seguida, você pode usar o seguinte tipo de código (completamente rasgado daquela mesma resposta por 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

Não tenho certeza, se isso ajuda

declare @s varchar(50)
set @s='Northwind'

declare @t nvarchar(100)
set @t = 'select * from ' + @s + '.[dbo].[Customers]'

execute sp_executesql @t

Se você estiver usando SQL Server, você pode configurar variáveis ??globais para scripts inteiros como:

:setvar sourceDB "lalalallalal"

e posterior utilização no script como:

$(sourceDB)

Faça o modo SQLCMD certeza está em no Server Managment Studi, você pode fazer isso através do menu superior, clique consulta e de alternância Modo SQLCMD diante.

Mais sobre o tema pode ser encontrada aqui: Documentação MS

tabelas temporárias são mantidas ao longo declarações ir, então ...

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

Não é bonito, mas funciona

Crie seus próprios procedimentos armazenados que salvar / carga para uma tabela temporária.

MyVariableSave   -- Saves variable to temporary table. 
MyVariableLoad   -- Loads variable from temporary table.

Em seguida, você pode usar isto:

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)))

Output:

Test stored procedures for load/save of variables across GO statements:
  - Set @MyVariable = 42
  - GO statement resets all variables
  - Get @MyVariable = 42

Você também pode usar estes:

exec dbo.MyVariableList       -- Lists all variables in the temporary table.
exec dbo.MyVariableDeleteAll  -- Deletes all variables in the temporary table.

Saída de exec dbo.MyVariableList:

Name    Value
test    42

Acontece que ser capaz de listar todas as variáveis ??em uma tabela é realmente muito útil. Assim, mesmo se você não carregar uma variável mais tarde, a sua grande para fins de depuração para ver tudo em um só lugar.

Isto usa uma tabela temporária com um prefixo ##, por isso é apenas o suficiente para sobreviver a uma declaração GO. Pretende-se para ser usado dentro de um único script.

e os procedimentos armazenados:

-- 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

Se você só precisa de um sim binárias / não (como se existe uma coluna), então você pode usar SET NOEXEC ON para desativar a execução de instruções. obras SET NOEXEC ON todo GO (em toda a lotes). Mas lembre-se de transformar EXEC para trás em com SET NOEXEC OFF no final do script.

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

Isso compila declarações, mas não executá-los. Então, você ainda vai ter "erros de compilação" se você faz referência esquema que não existe. Por isso, trabalha para "desligar" o script segundo prazo (o que estou fazendo), mas não funciona para desligar partes do script em 1º de prazo, porque você ainda vai receber erros de compilação se referenciar colunas ou tabelas que don 't ainda existe.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top