Czy istnieje sposób na utrwalenie zmiennej w trakcie przejścia?
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')
Zobacz to pytanie SO dla wiersza „USE @bob”.
Odpowiedzi:
Plik
go
Polecenie służy do dzielenia kodu w oddzielnych partiach. Jeśli to jest dokładnie to, co chcesz zrobić, powinieneś tego użyć, ale oznacza to, że partie są w rzeczywistości oddzielne i nie możesz udostępniać zmiennych między nimi.W twoim przypadku rozwiązanie jest proste; możesz po prostu usunąć
go
instrukcje, nie są one potrzebne w tym kodzie.Uwaga dodatkowa: nie możesz użyć zmiennej w
use
instrukcji, musi to być nazwa bazy danych.źródło
go
Polecenie służy do dzielenia kodu na oddzielne partie. Jeśli to jest to, co chcesz zrobić, powinieneś tego użyć, ale oznacza to, że partie są w rzeczywistości oddzielne i nie możesz udostępniać zmiennych między nimi.Użyj tabeli tymczasowej:
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
źródło
Wolę tę odpowiedź z tego pytania Global Variables with GO
Co ma dodatkową zaletę, że możesz robić to, co pierwotnie chciałeś zrobić.
Zastrzeżenie polega na tym, że musisz włączyć tryb SQLCMD (w sekcji Zapytanie-> SQLCMD) lub włączyć go domyślnie dla wszystkich okien zapytań (Narzędzia-> Opcje, a następnie Wyniki zapytania-> Domyślnie, otwieraj nowe zapytania w trybie SQLCMD)
Następnie możesz użyć następującego typu kodu (całkowicie wyrwany z tej samej odpowiedzi przez Oscara E. Fraxedasa 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
źródło
Jeśli używasz SQL Server, możesz ustawić zmienne globalne dla całych skryptów, takich jak:
i użyj później w skrypcie jako:
Upewnij się, że tryb SQLCMD jest włączony w programie Server Managment Studi. Możesz to zrobić w górnym menu Kliknij Zapytanie i włącz tryb SQLCMD.
Więcej na ten temat można znaleźć tutaj: Dokumentacja MS
źródło
Nie jestem pewien, czy to pomoże
declare @s varchar(50) set @s='Northwind' declare @t nvarchar(100) set @t = 'select * from ' + @s + '.[dbo].[Customers]' execute sp_executesql @t
źródło
Tabele tymczasowe są zachowywane w instrukcjach GO, więc ...
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
Nie jest ładna, ale działa
źródło
Utwórz własne procedury składowane, które zapisują / ładują do tabeli tymczasowej.
MyVariableSave -- Saves variable to temporary table. MyVariableLoad -- Loads variable from temporary table.
Następnie możesz użyć tego:
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)))
Wynik:
Test stored procedures for load/save of variables across GO statements: - Set @MyVariable = 42 - GO statement resets all variables - Get @MyVariable = 42
Możesz również użyć tych:
exec dbo.MyVariableList -- Lists all variables in the temporary table. exec dbo.MyVariableDeleteAll -- Deletes all variables in the temporary table.
Wyjście
exec dbo.MyVariableList
:Okazuje się, że możliwość wyświetlenia wszystkich zmiennych w tabeli jest w rzeczywistości całkiem przydatna. Więc nawet jeśli później nie załadujesz zmiennej, świetnie nadaje się do debugowania, aby zobaczyć wszystko w jednym miejscu.
Używa tymczasowej tabeli z rozszerzeniem
##
prefiksem, więc wystarczy przetrwać instrukcję GO. Jest przeznaczony do użycia w jednym skrypcie.Oraz procedury składowane:
-- 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
źródło
Jeśli potrzebujesz tylko binarnego tak / nie (np. Jeśli kolumna istnieje), możesz użyć,
SET NOEXEC ON
aby wyłączyć wykonywanie instrukcji.SET NOEXEC ON
działa w GO (w partiach). Ale należy pamiętać, aby włączyć EXEC plecami zeSET NOEXEC OFF
na końcu skryptu.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
To kompiluje instrukcje, ale ich nie wykonuje. Więc nadal będziesz otrzymywać „błędy kompilacji”, jeśli odwołasz się do schematu, który nie istnieje. Więc działa, aby "wyłączyć" skrypt po drugim uruchomieniu (co robię), ale nie działa, aby wyłączyć części skryptu przy pierwszym uruchomieniu, ponieważ nadal będziesz otrzymywać błędy kompilacji, jeśli odwołujesz się do kolumn lub tabel, które nie jeszcze nie istnieje.
źródło
Możesz skorzystać z NOEXEC, postępując zgodnie z poniższymi krokami:
Utwórz tabelę
#temp_procedure_version(procedure_version varchar(5),pointer varchar(20))
wstaw wersje procedur i wskaźnik do wersji do tabeli tymczasowej
#temp_procedure_version
- przykładowy wskaźnik wersji_procedury
włóż w
temp_procedure_version
wartości (1.0, „pierwsza wersja”)włóż w
temp_procedure_version
wartości (2.0, „wersja ostateczna”)następnie pobierz wersję procedury, możesz użyć warunku gdzie, jak w poniższej instrukcji
Wybierz
@ProcedureVersion=ProcedureVersion
z#temp_procedure_version
którympointer='first version'
IF (@ProcedureVersion='1.0') BEGIN SET NOEXEC OFF --code execution on END ELSE BEGIN SET NOEXEC ON --code execution off END
--wstaw procedurę w wersji 1.0 tutaj
Utwórz wersję procedury 1.0 jako .....
SET NOEXEC OFF -- execution is ON
Wybierz
@ProcedureVersion=ProcedureVersion
z#temp_procedure_version
gdzie pointer = „ostatecznej wersji”IF (@ProcedureVersion='2.0') BEGIN SET NOEXEC OFF --code execution on END ELSE BEGIN SET NOEXEC ON --code execution off END
Utwórz wersję procedury 2.0 jako .....
SET NOEXEC OFF -- execution is ON
- upuść tabelę tymczasową
Drop table
#temp_procedure_version
źródło