Проблема с динамическим запросом Sql

#sql #sql-server

#sql #sql-сервер

Вопрос:

я пытаюсь написать динамический sql. ниже приведена моя хранимая процедура, и у нее ошибка при добавлении sql-запроса к @SQLSTATEMENT может ли кто-нибудь помочь мне решить эту проблему? он показывает ошибку под знаком

НАПРИМЕР, SET @SQLSTATEMENT ‘ И TA.AreaID=’ @AreaID ‘ ‘

 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=' @AreaID ' '
END

IF @ABSID<>'0' 
BEGIN
SET @SQLSTATEMENT   ' AND TB.ABSID=' @ABSID ' '
END

IF @DisciplineID<>'0' 
BEGIN
SET @SQLSTATEMENT   ' AND DC.DisciplineID=' @DisciplineID ' '
END

IF @CPOID<>'0' 
BEGIN
SET @SQLSTATEMENT   ' AND CPO.CPOID=' @CPOID ' '
END

IF @DocumentTypeID<>'0' 
BEGIN
SET @SQLSTATEMENT   ' AND DT.DocumentTypeID=' @DocumentTypeID ' '
END

EXEC(@SQLSTATEMENT)

END
  

Ответ №1:

Попробуйте

 SET @SQLSTATEMENT = @SQLSTATEMENT     <rest>
  

т.е.

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

Ответ №2:

@Area идентификатор объявлен как INT , вам нужно привести его к varchar , чтобы иметь возможность его добавить.

Попробуйте это:

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

Ответ №3:

Другим вариантом может быть использование запроса, который не требует динамического 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).

Это вполне может привести к улучшению запроса, который можно кэшировать и использовать повторно. Однако следует остерегаться перехвата параметров: если вы запустите этот SP в первый раз со всеми параметрами = 0, оптимизатор выберет (и кэширует) совсем другой план выполнения, чем если бы большинство параметров отличались от нуля.