Est-il possible de conserver une variable d'un coup?
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')
Voir cette question SO pour la ligne 'USE @bob'.
La commande go
permet de scinder le code en lots séparés. Si c'est exactement ce que vous voulez faire, vous devriez l'utiliser, mais cela signifie que les lots sont en réalité séparés et que vous ne pouvez pas partager de variables entre eux.
Dans votre cas, la solution est simple. vous pouvez simplement supprimer les instructions go
, elles ne sont pas nécessaires dans ce code.
Note latérale: Vous ne pouvez pas utiliser une variable dans une instruction use
, il doit s'agir du nom d'une base de données.
Utilisez une table temporaire:
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
Je préfère la this réponse de cette question Global Variables with GO
Ce qui présente l’avantage supplémentaire de pouvoir faire ce que vous vouliez faire au départ.
L'avertissement est que vous devez activer le mode SQLCMD (sous Query-> SQLCMD) ou l'activer par défaut pour toutes les fenêtres de requête (Outils-> Options puis Query Results-> Par défaut, ouvrir de nouvelles requêtes en mode SQLCMD)
Ensuite, vous pouvez utiliser le type de code suivant (complètement arraché de la même réponse par 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
vous pouvez utiliser SQL dynamique, soyez simplement conscient des risques de sécurité (pas à 100% sur le bon syntex)
déclarer @bob nvarchar (50)
declare @sql nvarchar(max)
set @bob='SweetDB'
set @sql = 'Use ' + @bob
execute sp_executesql @sql
Si vous utilisez SQL Server, vous pouvez configurer des variables globales pour des scripts complets tels que:
:setvar sourceDB "lalalallalal"
et utiliser plus tard dans le script comme:
$(sourceDB)
Assurez-vous que le mode SQLCMD est activé dans Server Managment Studi. Vous pouvez le faire via le menu principal. Cliquez sur Requête et activez le mode SQLCMD.
Plus d'informations sur le sujet peuvent être trouvés ici: Documentation MS
Pas sûr, si cela aide
declare @s varchar(50)
set @s='Northwind'
declare @t nvarchar(100)
set @t = 'select * from ' + @s + '.[dbo].[Customers]'
execute sp_executesql @t
Si vous avez juste besoin d'un oui/non binaire (comme s'il y avait une colonne), vous pouvez utiliser SET NOEXEC ON
pour désactiver l'exécution des instructions. SET NOEXEC ON
fonctionne sur GO (sur plusieurs lots). Mais n'oubliez pas de réactiver EXEC avec SET NOEXEC OFF
à la fin du 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
Cela compile les instructions mais ne les exécute pas. Donc, vous aurez toujours des "erreurs de compilation" si vous référencez un schéma qui n'existe pas. Cela fonctionne donc pour "désactiver" le script 2ème exécution (ce que je fais), mais ne permet pas de désactiver des parties du script lors de la première exécution, car vous aurez toujours des erreurs de compilation si vous faites référence à des colonnes ou des tables n'existe pas encore.
Les tables temporaires sont conservées sur les instructions GO, donc ...
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
Ce n'est pas joli, mais ça marche
Créez vos propres procédures stockées qui sauvegardent/chargent dans une table temporaire.
MyVariableSave -- Saves variable to temporary table.
MyVariableLoad -- Loads variable from temporary table.
Ensuite, vous pouvez utiliser ceci:
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)))
Sortie:
Test stored procedures for load/save of variables across GO statements:
- Set @MyVariable = 42
- GO statement resets all variables
- Get @MyVariable = 42
Vous pouvez également utiliser ceux-ci:
exec dbo.MyVariableList -- Lists all variables in the temporary table.
exec dbo.MyVariableDeleteAll -- Deletes all variables in the temporary table.
Sortie de exec dbo.MyVariableList
:
Name Value
test 42
En fait, il est très utile de pouvoir répertorier toutes les variables d’un tableau. Ainsi, même si vous ne chargez pas une variable plus tard, il est très utile, à des fins de débogage, de tout voir au même endroit.
Ceci utilise une table temporaire avec un préfixe ##
, il suffit donc de survivre à une instruction GO. Il est destiné à être utilisé dans un seul script.
Et les procédures stockées:
-- 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