2017-03-21 10 views
2

SqlCmdモードを使用する単一の呼び出しスクリプトに含めることを試みているバルクデータのインポートを実行する一連のスクリプトがあります。私が持っている問題は、各スクリプトにはパスまたは共通オブジェクトを定義する宣言された変数のセットが含まれているということです。 '呼び出し'スクリプトを実行すると、varsがすでに宣言されているというエラーが表示されます。複数のスクリプト間で共通のT-SQLスクリプトで変数を宣言する方法

個々のスクリプトから宣言を引き出すと、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 + ''')' 

例 - あなたは3つのことを行うことによって、これを達成することができるはず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

スクリプトの関連部分を表示できますか? –

+0

[スクリプト変数](https://msdn.microsoft.com/en-us/library/ms188714.aspx)を見ましたか?すべてのスクリプトで同じスクリプト変数を定義し、その値をコマンドラインか ':Setvar'ステートメントを使って渡すことができます。それがSSMSとSSDTスクリプトの仕組みです。 –

+0

サンプルテーブルのデータと期待される結果をフォーマットしたテキストで追加してください。 現在のクエリの試行も表示 – TheGameiswar

答えて

2

を使用してファイル名を指定して実行:

  1. mの変数を宣言しないでください。アスタースクリプト。ように、変数名の末尾に、スクリプトIDを持つ変数を宣言し、また、メインスクリプトから離れて実行する必要が含まれたスクリプトのそれぞれにおいて

    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. :代わりに、ローカルの一時テーブルを作成彼らは自分や他のスクリプトの変数と一緒に存在することができます。

    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. decla後各スクリプト内の変数を鳴らす、ローカルの一時テーブルの値に基づいてそれらを設定します。

    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; 
    

    各スクリプトを個別に実行すると、変数はデフォルト値を保持します。それらがメインスクリプト内で実行されると、ローカル一時表が存在し、それらのデフォルト値を上書きします。

OR

  1. ここでも、設定値を保持するために、メインスクリプトでもないローカルの一時テーブルを何も宣言していません。

  2. あなたのSQLCMD変数のすべてを設定します:r経由で読み込まれるインクルードファイルを作成します。

    :r C:\AppConfigStuff\CommonIncludeConfigVariables.sql 
    
  3. :ファイルが含まれている一般的に読み、各スクリプトの先頭に

    :setvar SomePath "C:\go\here\for\some\reason\" 
    :setvar CommonObject "objectName" 
    :setvar SomeMaxValue 55 
    
  4. メインスクリプトとは別に実行する必要があるインクルードされた各スクリプトでは、変数名の末尾にスクリプトIDを付けて変数を宣言します。 CRIPTの変数は、デフォルト値として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"ステートメントを入れない理由があるときは、矛盾します。

さらに、2番目の方法では、すべてのT-SQL変数参照をSQLCMD変数参照(たとえば= $(IntVar)または= N'$(StringVar)')に置き換えると、最初にT-SQL変数が不要になってしまう可能性があります。 。

+0

ありがとうsrutzky。私はあなたの最初のオプションと一緒に行き、それは私が必要なものを提供しました。最終的に私はスクリプトをSPに移行することに決めましたが、これはその間に機能します。 – TravisPUK

関連する問題