2011-02-01 7 views
0

OK SQL 전문가 또는 DBA가 아니므로이 모든 것을 함께 수행하는 것이 더 좋은 방법이라면, 자유롭게 의견을 말하십시오.Begin and End 문을 사용하여 동적 TSQL 쿼리를 작성하는 방법

그러나 특별히 필요한 작업은 dyanmic SQL을 사용하여 중복 값을 삽입하지 않는 기존의 저장 프로 시저를 향상시키는 것입니다. 단일 테이블에 specefic 때 자체 SQL은 케이크 한 조각입니다. 지금 당장은 여러 테이블에서 일반적으로 작동하는 TSQL을 사용하는 일반 저장 프로 시저에 문제가 있습니다. 문제는 BEGIN 및 END 문과 관련되어 있습니다.

SET @Query = 'IF NOT EXISTS (SELECT ' + @DescriptionFieldName + ' 
     FROM '+ @TableName +' 
     WHERE (' + @DescriptionFieldName + ' = ''' + @DescriptionValue + ''') 

    BEGIN 
     INSERT INTO '+ @TableName +' (' + @DescriptionFieldName + ', LastUser, LastUpdate) VALUES ('''+ ISNULL(@DescriptionValue, '') +''', '''+ ISNULL(@LastUser, '') +''',Convert(Varchar, GetDate())) ' + 'SELECT CAST(scope_identity() AS int); 
    END' 

EXEC (@Query) 

나는 PRINT에 EXEC를 변경

이 모든 확인 구문 현명 할을 표시하지만, EXEC 사용할 때 다음과 같은 오류를 제공합니다 : 키워드 근처

"잘못된 구문을 'BEGIN' . "

누구든지이 문제를 해결하여 쿼리가 작동하는 방법에 대한 아이디어가 있습니까?

감사합니다.

답변

2

where 절 다음에 괄호가 누락 된 것 같습니다.

SET @Query = 'IF NOT EXISTS (SELECT ' + @DescriptionFieldName + ' 
     FROM '+ @TableName +' 
     WHERE (' + @DescriptionFieldName + ' = ' + @DescriptionValue + ')) 

    BEGIN 
     INSERT INTO '+ @TableName +' (' + @DescriptionFieldName + ', LastUser, LastUpdate) VALUES ('''+ ISNULL(@DescriptionValue, '') +''', '''+ ISNULL(@LastUser, '') +''',Convert(Varchar, GetDate())) ' + 'SELECT CAST(scope_identity() AS int); 
    END' 
+0

결국 좋은 시작은 BEGIN과 END와 관련이 없다. 또한 varchar이므로 WHERE ('+ @DescriptionFieldName +'= ''+ @DescriptionValue + ''))) @DescriptionValue (미래의 독자를 위해 수정 된 원본 게시물) 주위에 (3) 틱 표시를 추가해야했습니다. 그 (3) 틱 방법이 최선의 방법인가요? – atconway

1

FWIW는 생산을 위해 또는 내가 그것을 좀 더 쉽게 유지할 수있는 템플릿을 사용하려면 코드 생성에서 동적 SQL을가 온 - 더 - 플라이를 처리 할 때 (당신은 또한 인 줄 바꿈을 포함 할 수 있습니다

DECLARE @template AS varchar(max) = ' 
    IF NOT EXISTS (
     SELECT {@DescriptionFieldName} -- Note this is unnecessary 
     FROM {@TableName} 
     WHERE ({@DescriptionFieldName} = ''{@DescriptionValue}'' 
    ) 
    BEGIN 
     INSERT INTO {@TableName} ({@DescriptionFieldName}, LastUser, LastUpdate) 
     VALUES (''{@DescriptionValue}'', ''{@LastUser}'', ''{@LastUpdate}''); 
    END 
' 

DECLARE @Query AS varchar(max) = @template 
SET @Query = REPLACE(@Query, '{@DescriptionFieldName}', @DescriptionFieldName) 
SET @Query = REPLACE(@Query, '{@TableName}', @TableName) 
SET @Query = REPLACE(@Query, '{@DescriptionValue}', ISNULL(@DescriptionValue, '')) 
SET @Query = REPLACE(@Query, '{@LastUser}', ISNULL(@LastUser, '')) 
SET @Query = REPLACE(@Query, '{@LastUpdate}', @LastUpdate) 

PRINT @Query 
EXEC (@Query) 

당신은 여전히 ​​따옴표를 두 배로,하지만 당신은 문자열을 추가 할 필요가 없습니다 : - 좋은 더 망각은 CHAR (13)/CHAR (10) 또는 따옴표 앞에 공백이 필요)를 삽입 없습니다 , 매개 변수를 바꾸는 것을 잊었을 때 분명하고, 상황이 바뀌어야 할 때 코드에 삽입을 반복하지 않습니다.

또한 적절한 서식도 둥지 당신을 대체하고 당신이 할 수있는, 그것을 할 수있는합니다 (존재에 원래는 WHERE 부분에 같은 문제가 없었다)이 @DescriptionValue에서 NULL에 문제가있을 수 있음을

note 참고 심지어 읽을 수있다 :

DECLARE @Query AS varchar(max) = @template 
SET @Query = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@Query 
       ,'{@DescriptionFieldName}', @DescriptionFieldName) 
       ,'{@TableName}', @TableName) 
       ,'{@DescriptionValue}', ISNULL(@DescriptionValue, '')) 
       ,'{@LastUser}', ISNULL(@LastUser, '')) 
       ,'{@LastUpdate}', @LastUpdate) 
+0

아주 좋은이 원본 TSQL에 '개선'으로이 방법을 사용합니다. 말씀 드리고 보여 주셔서 감사합니다. – atconway

+0

BTW, "SELECT {@DescriptionFieldName} - 언급 할 필요가 없습니다"라는 메시지가 나타납니다. "키워드 'FROM'근처에 구문이 잘못되었습니다.". 최소한 1 개의 필드 만 선택하면 안 될까요? 대신 무엇을 넣었습니까? – atconway

+1

@atconway 당신은 SELECT *를 할 수 있습니다 (일반 SELECT에있는 것과 같이 EXISTS에서 SELECT *를 사용하는 일반적인 아니오는 아닙니다) 또는 SELECT 1을 사용할 수 있습니다. 변수 삽입을 할 필요가 없음을 의미합니다. –

관련 문제