代码之家  ›  专栏  ›  技术社区  ›  NitroxDM

有没有一种方法可以在整个过程中持久化变量?

  •  64
  • NitroxDM  · 技术社区  · 17 年前

    有没有一种方法可以在整个过程中持久化变量?

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

    看到这个了吗 SO “使用@bob”行的问题。

    7 回复  |  直到 7 年前
        1
  •  141
  •   RBarryYoung    17 年前

    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
    
        2
  •  34
  •   Guffa    11 年前

    这个 go 命令用于将代码拆分为单独的批。如果这正是您想要做的,那么您应该使用它,但这意味着批处理实际上是分开的,您不能在它们之间共享变量。

    在您的情况下,解决方案很简单;您只需删除 语句,则该代码中不需要它们。

    旁注:您不能在应用程序中使用变量 use 语句,它必须是数据库的名称。

        3
  •  17
  •   Community Mohan Dere    9 年前

    我更喜欢这个 this 这个问题的答案 Global Variables with GO

    这还有一个额外的好处,那就是能够做你原本想做的事情。

    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
    
        4
  •  4
  •   CodeSmith    9 年前

    如果您使用的是SQL Server,则可以为整个脚本设置全局变量,如:

    :setvar sourceDB "lalalallalal"
    

    并在脚本的后面部分用作:

    $(sourceDB)
    

    确保服务器管理Studi中的SQLCMD模式已打开,您可以通过顶部菜单单击Query并打开SQLCMD模式来执行此操作。

    有关此主题的更多信息,请参见: MS Documentation

        5
  •  1
  •   Remco Nonhebel    8 年前

    临时表是保留的over GO语句,所以。。。

    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
    

    虽然不漂亮,但它很管用

        6
  •  1
  •   Contango    7 年前

    创建自己的存储过程,将其保存/加载到临时表中。

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

    然后你可以使用这个:

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

    输出:

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

    您也可以使用这些:

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

    产量 exec dbo.MyVariableList :

    Name    Value
    test    42
    

    事实证明,能够列出表中的所有变量实际上非常有用。因此,即使以后不加载变量,在一个地方查看所有内容对于调试来说也是非常好的。

    这将使用带有 ## 前缀,所以它只足以在GO语句中生存。它打算在单个脚本中使用。

    以及存储过程:

    -- 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
    
        7
  •  0
  •   shahkalpesh    17 年前

    不确定,如果这有帮助的话

    declare @s varchar(50)
    set @s='Northwind'
    
    declare @t nvarchar(100)
    set @t = 'select * from ' + @s + '.[dbo].[Customers]'
    
    execute sp_executesql @t
        8
  •  0
  •   yzorg    7 年前

    如果您只需要一个二进制的yes/no(比如存在一列),那么您可以使用 SET NOEXEC ON 禁用语句的执行。 打开NOEXEC 跨GO(跨批次)工作。但是 记住重新打开EXEC 具有 SET NOEXEC OFF 在脚本的末尾。

    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
    

    这会编译语句,但不会执行它们。所以,如果引用不存在的模式,仍然会得到“编译错误”。因此,它可以在第二次运行时“关闭”脚本(我正在执行的操作),但在第一次运行时关闭部分脚本并不起作用,因为如果引用尚不存在的列或表,仍然会出现编译错误。

        9
  •  0
  •   Adrian Mole Chris    6 年前

    创建表

    #temp_procedure_version(procedure_version varchar(5),pointer varchar(20))
    

    将过程版本和指向该版本的指针插入临时表 #temp_procedure_version

    --示例过程\u版本指针

    插入 temp_procedure_version 值(1.0,“第一个版本”)

    插入 临时程序版本 值(2.0,“最终版本”)

    然后检索过程版本,您可以使用where条件,如下语句所示

    @ProcedureVersion=ProcedureVersion 从…起 哪里 pointer='first version'

    IF (@ProcedureVersion='1.0')
        BEGIN
        SET NOEXEC OFF  --code execution on 
        END
    ELSE
        BEGIN 
        SET NOEXEC ON  --code execution off
        END 
    

    --在此处插入过程版本1.0

    将过程版本1.0创建为。。。。。

    SET NOEXEC OFF -- execution is ON
    

    选择 @ProcedureVersion=ProcedureVersion 从…起 #临时程序版本 哪里 指针='最终版本'

    IF (@ProcedureVersion='2.0')
        BEGIN
        SET NOEXEC OFF  --code execution on 
        END
    ELSE
        BEGIN 
        SET NOEXEC ON  --code execution off
        END 
    

    将过程版本2.0创建为。。。。。

    --放下临时表

    升降台 #临时程序版本