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

时间:2015-11-03 13:18:17

标签: tsql stored-procedures common-table-expression

我想使用CTE(公用表表达式)

重写一个正常运行但速度慢的存储过程

我有一个很大的存储过程,我根据使用的参数构建nececary SQL dynamicaly。目前有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 

Everithing的工作就像一个魅力。没问题。只有性能问题。要解决其中之一,我会尝试使用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与多个变量一起使用?直到现在我发现的只是一个,也许是两个变量的查询。

1 个答案:

答案 0 :(得分:0)

你可以尝试:

WITH DataSQL AS
(
     SELECT   @SqlSelect SqlSelect
     ,        @SqlFromFast SqlFromFast
     ,        etcetera
)

确保您提供别名,否则它将无效。我怀疑它会对你的性能问题有所帮助。您可以尝试使用临时表,通常更快。你也可以尝试使用内部变量:

DECLARE @Select VARCHAR(MAX) = @SQLSelect 

然后使用它们,这可能有助于优化器,但这取决于您的数据。