2017-03-21 4 views
2

SqlCmd 모드를 사용하는 단일 '호출'스크립트에 포함시키려는 대량 데이터 가져 오기를 수행 할 스크립트 집합이 있습니다. 내가 가진 문제는 각 스크립트가 경로 또는 공통 객체를 정의하는 동일한 선언 된 집합을 포함한다는 것입니다. '호출하는'스크립트를 실행하면 vars가 이미 선언 된 오류가 발생합니다.여러 스크립트에서 공통적으로 사용되는 T-SQL 스크립트에서 변수를 선언하는 방법

개별 스크립트에서 선언을 가져 오는 경우 Intellisense는 물론 선언되지 않았다고 불평합니다. 스크립트 자체도 '호출'스크립트와 분리하여 실행해야하므로 이상적으로 개별 스크립트에서도 vars도 선언해야합니다.

감사합니다.

예 : 공통 개별 스크립트 선언하고 초기 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 + ''')' 

예 -

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

을 SQLCMD 모드를 사용하여 당신은 세 가지를 수행하여이 작업을 수행 할 수 있어야 실행

  1. m 애 스터 스크립트. 또한 주요 스크립트를 별도로 실행해야 포함 된 스크립트의 각에서

    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; 
    

    또 다른 스크립트 것 : decla 후

    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. 하여 SQLCMD 변수의 모든 설정 :r를 통해에서 읽을 수 있도록 포함 파일 만들기 : 그 공통 포함 파일을 읽어 각 스크립트의 상단에

    :setvar SomePath "C:\go\here\for\some\reason\" 
    :setvar CommonObject "objectName" 
    :setvar SomeMaxValue 55 
    
  3. 을 :

    :r C:\AppConfigStuff\CommonIncludeConfigVariables.sql 
    
  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"문을 입력하지 않은 다른 이유가있는 경우 충돌이 발생합니다. 당신이 SQLCMD 변수 참조 모든 T-SQL 변수 참조 (예 : = $(IntVar) 또는 = N'$(StringVar)'를) 대체 할 경우

그리고, 두 번째 방법으로, 당신은 아마 멀리도 처음에 T-SQL 변수를 필요로하지 않는로 얻을 수 있습니다 .

+0

감사합니다. srutzky. 나는 당신의 첫 번째 선택권을 가지고 나가서 필요한 것을 제공했습니다. 궁극적으로 나는 스크립트를 SP로 마이그레이션하기로 결정했으나, 중간에 작동 할 것입니다. – TravisPUK