Tsql 如何将参数传递给sp内的公共表表达式?

Tsql 如何将参数传递给sp内的公共表表达式?,tsql,stored-procedures,common-table-expression,Tsql,Stored Procedures,Common Table Expression,我想使用CTE(公共表表达式)重写一个运行正常但速度较慢的存储过程 我有一个大的存储过程,在这个过程中,我根据使用的参数构建必要的SQL动态。目前有27个参数,我组成了SQL字符串,在最后执行,它看起来像: DECLARE @SqlWhereClause NVARCHAR(MAX) SET @SqlWhereClause = ' WHERE ([InTimeStamp] BETWEEN ''' + CONVERT(VARCHAR(19), @fromDate, 120) + '''

我想使用CTE(公共表表达式)重写一个运行正常但速度较慢的存储过程

我有一个大的存储过程,在这个过程中,我根据使用的参数构建必要的SQL动态。目前有27个参数,我组成了SQL字符串,在最后执行,它看起来像:

    DECLARE @SqlWhereClause NVARCHAR(MAX)  
SET @SqlWhereClause = ' WHERE ([InTimeStamp] BETWEEN ''' + CONVERT(VARCHAR(19), @fromDate, 120) + ''' AND ''' + CONVERT(VARCHAR(19), @toDate, 120) + ''')'

IF @showOnlyErrors = '1'  
   BEGIN
     SET @SqlWhereClause += ' AND Status = ''Error'''  
    END

IF LEN(LTRIM(RTRIM(@docNo))) > 0  
  BEGIN  
    IF @matchExact = '1'   
      BEGIN
         SET @SqlWhereClause += ' AND DocumentNumber = ''' + @docNo + ''''  
      END
   ELSE
    BEGIN   
        SET @SqlWhereClause += ' AND (contains([DocumentNumber],'''+ @docNo +'''))'
    END 
  END     
最后,我添加分页并将其转换为最终的formSQL:

    IF CONVERT(int, LTRIM(RTRIM(@takeRows))) > 0   
   BEGIN
     SET @SqlOrderByClause += ' OFFSET ' + @rowNumberToSkip +' ROWS FETCH NEXT '+ @takeRows +' ROWS ONLY '
     Set @RowCount = ' Select @totalRecords = count(1) from  dbo.Messages WITH (NOLOCK) ' + @SqlWhereClause
   END

    SET @SQL = @SqlSelect + @SqlFrom + @SqlWhereClause + @SqlOrderByClause + ' ; '  + @RowCount  
    PRINT @SQL  
    EXECUTE sp_executesql @SQL, @params, @totalRecords OUTPUT 
每件事都像一个符咒一样起作用。没问题。只有性能问题。为了解决其中一个问题,我将尝试使用CTE(公共表扩展)

但这是行不通的:

   With DataSQL AS
    (@SqlSelect + @SqlFrom + @SqlWhereClause + @SqlOrderByClause),

   - incorrect syntax near @SqlSelect - Expecting '(' or Select.
我也试过这个:

     WITH DataSQL AS 
     ( Select @SqlSelect    From @SqlFromFast   
    Where @SqlWhereClause   Order By @SqlOrderByClause),
我得到:

    An expression of non-boolean type specified in a context where a condition is expected, near 'Order'
有什么想法吗?或者不可能对多个变量使用CTE?到目前为止,我只找到了一个或两个变量的查询。

您可以尝试:

WITH DataSQL AS
(
     SELECT   @SqlSelect SqlSelect
     ,        @SqlFromFast SqlFromFast
     ,        etcetera
)
请确保您提供别名,否则它将无法工作。不过,我怀疑这会对您的性能问题有所帮助。你可以试着使用临时表,这通常更快。您还可以尝试使用内部变量:

DECLARE @Select VARCHAR(MAX) = @SQLSelect 

而使用它们,这可能会帮助优化器,尽管这取决于您的数据。

什么是慢的?构建动态sql或执行动态sql?执行需要很长时间。另外,因为行数几乎和查询本身一样多。我在执行计划中查过,它有50%/50%你看过执行计划了吗?SSM是否建议使用任何索引?索引的问题在于,一方面我们有许多包含(如)搜索,其中索引没有帮助,另一方面,在总共27个搜索标准中,通常使用12-15个搜索标准。但其他的也在使用中。此表已经是一个聚合表,仅用于监视目的,因此更新不存在,插入通过批处理(每5分钟一次)完成,删除通过作业完成(删除所有早于52周的数据)。目前我检测到的最大瓶颈是@RowCount的第二个查询。它所用的时间与查询本身差不多。变量SqlSelect包含的不仅仅是一列,与SQLWHEREQUALE变量相同。设置@SqlSelect='[RecordId]、[TransactionId]、[Status]、[InTimeStamp]、[OutTimeStamp]、[Doctype]、[DocumentNumber]、[DocFormat]、。。。。。