¿Hay alguna forma de conservar una variable en un proceso?
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')
Vea esta pregunta SO para la línea 'USE @bob'.
Respuestas:
El
go
comando se usa para dividir el código en lotes separados. Si eso es exactamente lo que quiere hacer, entonces debería usarlo, pero significa que los lotes están realmente separados y no puede compartir variables entre ellos.En su caso, la solución es sencilla; simplemente puede eliminar las
go
declaraciones, no son necesarias en ese código.Nota al margen: no puede usar una variable en una
use
declaración, tiene que ser el nombre de una base de datos.fuente
go
comando se usa para dividir el código en lotes separados. Si eso es lo que quiere hacer, entonces debería usarlo, pero significa que los lotes están realmente separados y no puede compartir variables entre ellos.Utilice una mesa temporal:
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
fuente
Prefiero esta respuesta de esta pregunta Variables globales con GO
Lo cual tiene el beneficio adicional de poder hacer lo que originalmente quería hacer también.
La advertencia es que debe activar el modo SQLCMD (en Consulta-> SQLCMD) o activarlo de forma predeterminada para todas las ventanas de consulta (Herramientas-> Opciones y luego Resultados de la consulta-> Por defecto, abrir nuevas consultas en modo SQLCMD)
Luego puede usar el siguiente tipo de código (completamente extraído de la misma respuesta 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
fuente
Si está utilizando SQL Server, puede configurar variables globales para scripts completos como:
y usar más adelante en el script como:
Asegúrese de que el modo SQLCMD esté activado en Server Managment Studi, puede hacerlo a través del menú superior Haga clic en Consulta y active el modo SQLCMD.
Puede encontrar más información sobre el tema aquí: Documentación de MS
fuente
No estoy seguro si esto ayuda
declare @s varchar(50) set @s='Northwind' declare @t nvarchar(100) set @t = 'select * from ' + @s + '.[dbo].[Customers]' execute sp_executesql @t
fuente
Las tablas temporales se conservan sobre las declaraciones GO, así que ...
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
No es bonito, pero funciona
fuente
Cree sus propios procedimientos almacenados que se guardan / cargan en una tabla temporal.
MyVariableSave -- Saves variable to temporary table. MyVariableLoad -- Loads variable from temporary table.
Entonces puedes usar esto:
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)))
Salida:
Test stored procedures for load/save of variables across GO statements: - Set @MyVariable = 42 - GO statement resets all variables - Get @MyVariable = 42
También puede utilizar estos:
exec dbo.MyVariableList -- Lists all variables in the temporary table. exec dbo.MyVariableDeleteAll -- Deletes all variables in the temporary table.
Salida de
exec dbo.MyVariableList
:Resulta que poder enumerar todas las variables en una tabla es bastante útil. Entonces, incluso si no carga una variable más tarde, es excelente para fines de depuración ver todo en un solo lugar.
Esto usa una tabla temporal con un
##
prefijo, por lo que es suficiente para sobrevivir a una instrucción GO. Está destinado a utilizarse dentro de un único script.Y los procedimientos almacenados:
-- 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
fuente
Si solo necesita un sí / no binario (como si existiera una columna), puede usarlo
SET NOEXEC ON
para deshabilitar la ejecución de declaraciones.SET NOEXEC ON
funciona en GO (en lotes). Pero recuerde que debe dar marcha atrás en EXEC conSET NOEXEC OFF
al final de la secuencia de comandos.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
Esto compila declaraciones pero no las ejecuta. De modo que seguirá recibiendo "errores de compilación" si hace referencia a un esquema que no existe. Por lo tanto, funciona para "apagar" el script en la segunda ejecución (lo que estoy haciendo), pero no funciona para desactivar partes del script en la primera ejecución, porque todavía obtendrá errores de compilación si hace referencia a columnas o tablas que no funcionan. todavía no existe.
fuente
Puede hacer uso de NOEXEC siguiendo los pasos a continuación:
Crear mesa
#temp_procedure_version(procedure_version varchar(5),pointer varchar(20))
inserte versiones de procedimiento y puntero a la versión en una tabla temporal
#temp_procedure_version
--ejemplo puntero de versión_procedimiento
insertar en
temp_procedure_version
valores (1.0, 'primera versión')insertar en
temp_procedure_version
valores (2.0, 'versión final')luego recupere la versión del procedimiento, puede usar la condición where como en la siguiente declaración
Seleccionar
@ProcedureVersion=ProcedureVersion
de#temp_procedure_version
dondepointer='first version'
IF (@ProcedureVersion='1.0') BEGIN SET NOEXEC OFF --code execution on END ELSE BEGIN SET NOEXEC ON --code execution off END
--insertar el procedimiento versión 1.0 aquí
Cree el procedimiento versión 1.0 como .....
SET NOEXEC OFF -- execution is ON
Seleccione
@ProcedureVersion=ProcedureVersion
desde#temp_procedure_version
donde pointer = 'versión final'IF (@ProcedureVersion='2.0') BEGIN SET NOEXEC OFF --code execution on END ELSE BEGIN SET NOEXEC ON --code execution off END
Cree el procedimiento versión 2.0 como .....
SET NOEXEC OFF -- execution is ON
- suelta la tabla temporal
Mesa plegable
#temp_procedure_version
fuente