2011-10-08 6 views
0

동적 인 sql.following을 쓰려고하는데 내 저장 프로 시저가 있는데 SQL 쿼리를 @SQLSTATEMENT에 추가하면이 문제를 해결할 수 있습니까? 그것은 + 마크Sql 동적 쿼리 관련 문제

EX에서 오류를 보여줍니다 - 시도 SET의 @SQLSTATEMENT + 'AND TA.AreaID='[email protected]+' '

ALTER PROCEDURE spGetOverDueDocuments 
@AreaID INT =NULL, 
@DepartmentID INT= NULL, 
@ABSID INT =NULL, 
@DisciplineID INT = NULL, 
@CPOID INT = NULL, 
@DocumentTypeID INT = NULL, 
@DueType VaRCHAR(20) = NULL 
AS 
BEGIN 
DECLARE @SQLSTATEMENT VARCHAR(MAX) 


SELECT @SQLSTATEMENT = 'SELECT * '+ 
'FROM tblActionHeader AH INNER JOIN '+ 
'tblDocumentRevisionActionHeader DAH ON AH.ActionHeaderID=DAH.ActionHeaderID INNER JOIN '+ 
'tblDocumentRevision DR ON DAH.DocumentRevisionID=DR.DocumentRevisionID INNER JOIN '+ 
'tblDocumentHeader DH ON DR.DocumentHeaderID=DH.DocumentHeaderID INNER JOIN tblABS TB ON DH.ABSID=TB.ABSID ' + 
'INNER JOIN tblArea TA ON TA.AreaID=TB.AreaNo INNER JOIN tblContractPODocumentHeader CDH ON '+ 
' CDH.DocumentHeaderID=DH.DocumentHeaderID INNER JOIN tblDiscipline DC ON '+ 
' DH.DisciplineID=DC.DisciplineID INNER JOIN tblContractPO CPO ON CPO.CPOID=DH.CPOID INNER JOIN tblDocumentType DT '+ 
' ON DT.DocumentTypeID=DH.DocumentTypeID '+ 
'WHERE AH.ActionTypeID=4 ' 
IF @AreaID<>'0' 
BEGIN 
SET @SQLSTATEMENT + ' AND TA.AreaID='[email protected]+' ' 
END 

IF @ABSID<>'0' 
BEGIN 
SET @SQLSTATEMENT + ' AND TB.ABSID='[email protected]+' ' 
END 

IF @DisciplineID<>'0' 
BEGIN 
SET @SQLSTATEMENT + ' AND DC.DisciplineID='[email protected]+' ' 
END 

IF @CPOID<>'0' 
BEGIN 
SET @SQLSTATEMENT + ' AND CPO.CPOID='[email protected]+' ' 
END 

IF @DocumentTypeID<>'0' 
BEGIN 
SET @SQLSTATEMENT + ' AND DT.DocumentTypeID='[email protected]+' ' 
END 

EXEC(@SQLSTATEMENT) 

END 

답변

2

SET @SQLSTATEMENT = @SQLSTATEMENT + <rest> 

SET @SQLSTATEMENT = @SQLSTATEMENT + ' AND TA.AreaID='+STR(@AreaID)+' ' 
+0

고맙습니다. – chamara

2

@Area ID는 INT으로 선언되었으므로 추가 할 수 있으려면 varchar으로 변환해야합니다.

이 시도 :

SET @SQLSTATEMENT + ' AND TA.AreaID='+cast(@AreaID as varchar(30))+' ' 
+0

고맙습니다. – chamara

0

또 다른 옵션은 동적 SQL을 필요로하지 않는 쿼리를 사용하는 것입니다

이 것 한 가지 가능한 방법 :

SELECT * 
FROM tblActionHeader AH 
INNER JOIN tblDocumentRevisionActionHeader DAH ON AH.ActionHeaderID=DAH.ActionHeaderID 
INNER JOIN tblDocumentRevision DR ON DAH.DocumentRevisionID=DR.DocumentRevisionID 
INNER JOIN tblDocumentHeader DH ON DR.DocumentHeaderID=DH.DocumentHeaderID 
INNER JOIN tblABS TB ON DH.ABSID=TB.ABSID 
INNER JOIN tblArea TA ON TA.AreaID=TB.AreaNo 
INNER JOIN tblContractPODocumentHeader CDH ON CDH.DocumentHeaderID=DH.DocumentHeaderID 
INNER JOIN tblDiscipline DC ON DH.DisciplineID=DC.DisciplineID 
INNER JOIN tblContractPO CPO ON CPO.CPOID=DH.CPOID 
INNER JOIN tblDocumentType DT ON DT.DocumentTypeID=DH.DocumentTypeID 
WHERE TA.AreaID = (CASE WHEN @AreaID<>'0' THEN @AreaID ELSE TA.AreaId END) 
AND TA.ABSID = (CASE WHEN @ABSID<>'0' THEN @ABSID ELSE TA.ABSID END) 
AND DC.DisciplineID = (CASE WHEN @DisciplineID<>'0' THEN @DisciplineID ELSE DC.DisciplineID END) 
AND CPO.CPOID = (CASE WHEN @CPOID<>'0' THEN @CPOID ELSE TA.ABSID END) 
AND DT.DocumentTypeID = (CASE WHEN @DocumentTypeID<>'0' THEN @DocumentTypeID ELSE TA.ABSID END) 

에서 이 쿼리는 다른 값을 지정하지 않는 한 동적으로 추가 한 검색 조건자를 자신과 비교하도록 설정됩니다. null이 아니면 (NULL = NULL 또는 NULL = x에 대한 테스트는 항상 false이므로) null이 아닌 한이 작업이 작동합니다.

이렇게하면 캐싱하고 재사용 할 수있는 더 나은 쿼리가 생성 될 수 있습니다. 그러나주의해야 할 사항 중 하나는 매개 변수 스니핑입니다. 모든 매개 변수가 0 인이 SP를 처음 실행하면 옵티마이 저는 대부분의 매개 변수가 0이 아닌 경우와 매우 다른 실행 계획을 선택하고 캐시합니다.