Frage

Gibt es eine Möglichkeit, eine Variable über einen Sprung zu beharren?

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

Sehen Sie diese SO Frage nach der Zeile 'USE @bob'.

War es hilfreich?

Lösung

Der go Befehl wird verwendet, um Code in separate Chargen aufgeteilt. Wenn das ist genau das, was Sie tun wollen, dann sollten Sie es verwenden, aber es bedeutet, dass die Chargen tatsächlich getrennt sind, und Sie können keine Variablen zwischen ihnen teilen.

In Ihrem Fall ist die Lösung einfach; Sie können nur die go Aussagen entfernen, werden sie in diesem Code nicht benötigt wird.

Side. Hinweis: Sie können keine Variable in einer use Anweisung verwenden, hat es der Name einer Datenbank sein

Andere Tipps

Verwenden Sie eine temporäre Tabelle:

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

Ich ziehe den diese von dieser Frage beantworten Globale Variablen mit GO

, die den zusätzlichen Vorteil, der in der Lage ist zu tun, was man ursprünglich auch tun wollte.

Der Nachteil ist, dass Sie auf SQLCMD-Modus aktivieren müssen (unter Abfrage-> SQLCMD) oder schalten Sie ihn auf standardmäßig für alle Abfragefenster (Tools-> Optionen dann auf Abfrage Ergebnisse-> Standardmäßig öffnen neue Abfragen in SQLCMD-Modus )

Dann können Sie die folgenden Arten von Code verwenden (vollständig aus derselben Antwort von Oscar E. abgezockt 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

Nicht sicher, ob das hilft

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

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

execute sp_executesql @t

Wenn Sie SQL Server verwenden Sie können Setup globale Variablen für ganze Skripte wie:

:setvar sourceDB "lalalallalal"

und verwenden später in Skript wie:

$(sourceDB)

Stellen Sie sicher, SQLCMD-Modus in Server Managment Studi ist, können Sie über Top-Menü tun Abfrage klicken und wechseln SQLCMD-Modus auf.

Mehr zum Thema finden Sie hier: MS Dokumentation

Temp-Tabellen werden beibehalten über GO-Anweisungen, so ...

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

Es ist nicht schön, aber es funktioniert

Erstellen Sie Ihre eigenen gespeicherten Prozeduren, die / Last in eine temporäre Tabelle zu speichern.

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

Dann können Sie diese verwenden:

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

Ausgabe:

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

Sie können auch diese verwenden:

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

Ausgabe von exec dbo.MyVariableList:

Name    Value
test    42

Es stellt sich heraus, dass die Fähigkeit, alle Variablen in einer Tabelle aufzulisten eigentlich ganz nützlich ist. Also selbst wenn Sie später eine Variable nicht geladen werden, sein großes für Debugging-Zwecke alles an einem Ort zu sehen.

Dies verwendet eine temporäre Tabelle mit einem ## Präfix, so ist es nur genug, um eine GO-Anweisung, um zu überleben. Es ist beabsichtigt, innerhalb eines einzigen Skript verwendet werden.

Und die gespeicherten Prozeduren:

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

Wenn Sie nur ein binäres ja benötigen / nein (wie wenn eine Spalte vorhanden ist), dann können Sie SET NOEXEC ON verwenden Ausführung von Anweisungen zu deaktivieren. SET NOEXEC ON funktioniert über GO (über Chargen). Aber erinnern EXEC wieder zu aktivieren mit SET NOEXEC OFF am Ende des Skripts.

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

Dies kompiliert Aussagen sie jedoch nicht ausführen. So werden Sie noch erhalten „Fehler kompilieren“, wenn Sie Schema verweisen, die nicht existiert. So funktioniert es auf „deaktivieren“, um das Skript 2. Lauf (was ich tue), aber nicht funktioniert Teile des Skripts im 1. Lauf zu deaktivieren, da Sie noch Fehler kompilieren erhalten, wenn Referenzierung Spalten oder Tabellen, Don ‚t existieren noch.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top