2013-07-10 4 views
2

내가 사용하는 몇 가지 SQL 파일을 호출 TransactSQL to run another TransactSQL script :사용 방법 : setvar가 올바르게 설정 되었습니까?

:r C:\Scripts\Script1.sql 
:r C:\Scripts\Script2.sql 
:r C:\Scripts\Script3.sql 

여기에서 :r 통화에 대한이 아이디어를 가지고있다. Script1.sql 스크립트에는 코드에 다른 sql 스크립트 호출이있을 수도 있습니다.

이제 각 스크립트에 대한 설정을 정의하고 싶습니다. 예 : LastInsertedID을 정의하고 Script1.sql을 호출하기 직전에 SCOPE_IDENTITY() 값으로 설정합니다. 그리고이 스크립트는 이제이 변수를 사용하고 함께 작동합니다. 이렇게하려면

은 그래서 SQLCMD 스크립트 변수 (http://msdn.microsoft.com/de-de/library/ms188714.aspx)를 사용하여 그것들을 설정했다 :

:setvar LastInsertedID SCOPE_IDENTITY() 

나는 다음 Script1.sql에서 SELECT $(LastInsertedID을 쓸 수 그것은 나에게 올바른 값을 줄 것입니다.

나중에 내가 을 선택하기 전에 다른 INSERT 문을 처리하면 새로 삽입 된 행의 ID를 얻을 수 있기 때문에 이것이 정확하지 않다는 것을 알았습니다. :setvar은 현재의 값인 SCOPE_IDENTITY()을 저장하지 않고 더 이상 참조를 요구하지 않고 다시 호출하기 때문에 이런 경우 일 수 있습니다.

그래서 뭔가 다른 것을 시도하고 변수를 선언하고 현재 값 SCOPE_IDENTITY()을 할당 한 다음 :setvar으로 저장했습니다. 다음과 같이 보입니다.

DECLARE @LastInsertedID int 
SELECT @LastInsertedID = SCOPE_IDENTITY() 
:setvar LastInsertedID @LastInsertedID 
PRINT $(LastInsertedID) 

이 순간이 다시 정상적으로 돌아 왔습니다. 그러나 코드를 여러 개의 GO 섹션으로 구분하고 :setvar이 원하는 결과물을 다시 제공하지 않는다는 것을 깨달았습니다. 그것은 지금 당신에게 말하는 오류 메시지를 제공

DECLARE @LastInsertedID int 
SELECT @LastInsertedID = SCOPE_IDENTITY() 
:setvar LastInsertedID @LastInsertedID 

GO 

PRINT $(LastInsertedID) 

: Must declare the scalar variable @LastInsertedID

당신은 전 예에서 :setvarGO를 삽입합니다.

다시 변수 @LastInsertedID의 실제 값은 저장되지 않지만 더 이상 해당 컨텍스트에는 더 이상 존재하지 않는 변수 자체에 대한 참조가 저장됩니다.

내 질문은 이제 :setvar을 올바르게 사용하거나 어떻게이 문제를 원하는 출력으로 다르게 해결할 수 있습니까?

도움이나 의견을 보내 주셔서 감사합니다.

답변

1

sqlcmd 지정 문 (예 : :setvar)이 서버와 전혀 통신하지 않습니다. 그것들을 원시 매크로라고 생각하십시오. 그들은 런타임에 알게 될 변화하는 것들에 더 가깝습니다. sqlcmd에서 :setvar 문을 출력하고 sqlcmd에 대한 다른 호출을 통해 읽을 수있는 멋진 방법을 생각해 낼 수는 있지만 지나치게 번거롭고 깨지기 쉬운 것 같습니다. 무엇을 성취하려고합니까?

+0

일부 값을 설정하고이 값을 사용하여 스크립트를 실행하고 싶습니다. 예를 들면 다음과 같습니다. id를 1로 설정하고 id가 1 인 해당 항목에 대한 몇 가지 추가 데이터를 삽입하는 스크립트를 실행합니다. 그런 다음 id를 2로 설정하여 다시 사용합니다. 기본적으로 간단한 함수 호출이지만 스크립트 파일을 사용합니다. –

+0

그렇게하십시오. ': setvar ID 1'과 같은 일을 할 수 있고 스크립트의 SQL 부분에'dbo.tbl ($ (ID))'에 삽입하거나 SQL 변수 (예 : @id)에 할당 할 수 있습니다. 모든 목적과 목적을 위해 런타임시 sqlcmd가 변수의 값으로 대체 한 정적 텍스트처럼 $ (ID)를 처리하십시오. –

+0

아 ... 네가 도움을 원한다고 생각 했어. 엉덩이가되는 것은 좋은 방법이 아닙니다. 즉, SQL 변수가 sqlcmd 변수로 채우려는 역할을 수행합니다. 특히, sqlcmd 변수에 할당해야하는 이유가 무엇입니까? SQL 변수로는 할 수없는 sqlcmd 변수로 무엇을하려고합니까? –

4

"다시 : setvar는 @LastInsertedID 변수의 실제 값을 저장하지 않지만 더 이상 해당 컨텍스트에 더 이상 존재하지 않는 변수 자체에 대한 참조를 저장합니다."

Setvar는 실제로 변수에 대한 참조를 저장하지 않습니다. Setvar (및 변수 대체)는 선행 처리기이므로 텍스트 편집기 검색 &을 실행하는 것과 동일한 작업을 실행하기 직전에 파일에 대치합니다.

이렇게하면 더 명확하게 알 수 있습니다. SETVAR & 대체 무엇보다도 먼저 발생합니다. 그래서이 :

DECLARE @LastInsertedID int 
SELECT @LastInsertedID = SCOPE_IDENTITY() 
:setvar LastInsertedID @LastInsertedID 
GO 
PRINT $(LastInsertedID) 

이로 바뀝니다 :

DECLARE @LastInsertedID int 
SELECT @LastInsertedID = SCOPE_IDENTITY() 
GO 
PRINT @LastInsertedID 

그런 다음이 SQL 서버에서 실행합니다. @LastInsertedID는 GO 문 다음에 더 이상 정의되지 않으므로 작동하지 않습니다.

Setvar는 GO 블록에서 값을 보존하는 데 사용할 수 없습니다. 각 블록에는 자신의 범위가 있습니다 & 자신의 SQL 변수 집합입니다. 같은 GO 블록에서 모든 코드를 실행하거나 다른 두 블록 (임시 테이블, 전역 임시 테이블, proc 호출)간에 데이터를 전달하는 다른 방법을 찾아야합니다.