繁体   English   中英

如何在正在运行的多个脚本中通用的T-SQL脚本中声明变量

[英]How to declare variables in T-SQL scripts that are common across multiple scripts being run

我有一组脚本来执行批量数据导入,我试图将其包含在使用SqlCmd模式的单个“调用”脚本中。 我遇到的问题是每个脚本都包含定义路径或公共对象的同一组声明的变量。 当我运行'调用'脚本时,我得到了已经声明了变量的错误。

如果我从单个脚本中提取声明,Intellisense当然会抱怨它们没有被声明。 脚本本身也需要与“调用”脚本隔离运行,所以理想情况下我需要在各个脚本中声明的变量。

谢谢。

示例:通用单个脚本声明和初始SET

DECLARE @path varchar(256),
        @currPeriod varchar(25),
        @pastPeriod varchar(25),
        @period varchar(25),
        @fileName varchar(256),
        @sheet varchar(25),
        @sql varchar(MAX)

SET     @path = 'H:\Scripts\DataImport';
SET     @currPeriod = CONCAT(DATEPART(year,GETDATE()),'-',CONVERT(varchar(2), getdate(), 101));
SET     @pastPeriod =  CONCAT(DATEPART(year,DateAdd(month, -1, Convert(date, GETDATE()))),'-',CONVERT(varchar(2), DateAdd(month, -1, Convert(date, GetDate())), 101));
SET     @period = @pastPeriod;  -- Change to currPeriod or pastPeriod based on import type.
SET     @fileName = 'ReferenceClients-' + @period + '.xlsx';
SET     @sheet = '[Sheet1$]';

SET     @sql = 'INSERT INTO #TempRefClients
                SELECT *
                FROM OPENROWSET(''Microsoft.ACE.OLEDB.12.0'',
                                ''Excel 12.0; Database=' + @path + '\' + @period + '\' + @fileName + '; HDR=YES; IMEX=1'',
                                ''SELECT * FROM ' + @sheet + ''')'

调用脚本示例 - 使用SqlCmd模式运行

-- Ref Clients
BEGIN
    PRINT ' ';
    PRINT 'Importing Ref Clients';
    :r "H:\Scripts\DataImport\CurrentMonthScripts\BulkImport-RefClients.sql"
END;

-- Top Clients
BEGIN
    PRINT ' ';
    PRINT 'Importing Top Clients';
    :r "H:\Scripts\DataImport\CurrentMonthScripts\BulkImport-TopClients.sql"
END;

你应该能够通过做三件事来做到这一点:

  1. 不要在主脚本中声明变量。 而是创建一个本地临时表:

     CREATE TABLE #ConfigSettings ( [SomePath] NVARCHAR(500) NOT NULL, [CommonObjectA] NVARCHAR(128) NOT NULL, [SomeMaxValue] INT ); INSERT INTO #ConfigSettings VALUES (N'C:\\go\\here\\for\\some\\reason\\', N'objectName', 55); 
  2. 在每个包含的脚本中,还需要与主脚本分开运行,在变量名末尾声明带有脚本ID的变量,以便它们可以单独存在或与其他脚本的变量一起存在:

     DECLARE @SomePath_1 NVARCHAR(500) = N'default_when_run_individually', @CommonObjectA_1 NVARCHAR(128) = N'default_value', @SomeMaxValue_1 INT = default_value; 

    另一个脚本会有:

     DECLARE @SomePath_2 NVARCHAR(500) = N'default_when_run_individually', @CommonObjectA_2 NVARCHAR(128) = N'default_value', @SomeMaxValue_2 INT = default_value; 
  3. 在每个脚本中声明变量后,根据本地临时表中的值设置它们:

     IF (OBJECT_ID(N'tempdb..#ConfigSettings') IS NOT NULL) BEGIN SELECT @SomePath_1 = cnf.[SomePath], @CommonObjectA_1 = cnf.[CommonObjectA], @SomeMaxValue_1 = cnf.[SomeMaxValue] FROM #ConfigSettings cnf END; 

    每个脚本单独运行时,变量将保留其默认值。 当它们在主脚本中运行时,本地临时表将存在并将覆盖这些默认值。

要么

  1. 同样,不要在主脚本中声明任何内容,甚至不要在本地临时表中声明保存配置值。

  2. 通过以下方式创建要读入的包含文件:r设置所有SQLCMD变量:

     :setvar SomePath "C:\\go\\here\\for\\some\\reason\\" :setvar CommonObject "objectName" :setvar SomeMaxValue 55 
  3. 在每个脚本的顶部,读入该公共包含文件:

     :r C:\\AppConfigStuff\\CommonIncludeConfigVariables.sql 
  4. 在每个包含的脚本中,还需要与主脚本分开运行,在变量名称的末尾使用脚本ID声明变量,以便它们可以单独存在或与其他脚本的变量一起存在,并使用SQLCMD变量作为默认值:

     DECLARE @SomePath_1 NVARCHAR(500) = N'$(SomePath)', @CommonObjectA_1 NVARCHAR(128) = N'$(CommonObject)', @SomeMaxValue_1 INT = $(SomeMaxValue); 

    另一个脚本会有:

     DECLARE @SomePath_2 NVARCHAR(500) = N'$(SomePath)', @CommonObjectA_2 NVARCHAR(128) = N'$(CommonObject)', @SomeMaxValue_2 INT = $(SomeMaxValue); 

在这两种方法中,在每个单独的脚本中使用唯一的变量名称将消除任何冲突,尤其是当您有其他原因不在脚本之间放置“GO”语句时。

而且,在第二种方法中,如果用SQLCMD变量引用替换所有T-SQL变量引用(例如= $(IntVar)= N'$(StringVar)' = $(IntVar) ,您甚至可能首先不需要T-SQL变量。 = N'$(StringVar)' )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM