动态SQL,sp_executesql和重建动态sql语句 - 第1部分

时间:2011-02-05 03:05:28

标签: tsql stored-procedures

第1部分:在他的文章“T-SQL中的动态搜索条件...适用于SQL 2005及更早版本”中,Erland Sommarskog举例说明了如何将动态sql与sp_executesql一起使用。

http://www.sommarskog.se/dyn-search-2005.html#sp_executesql

SELECT @sql =                                                  -- 19
'SELECT o.OrderID, o.OrderDate, od.UnitPrice, od.Quantity,     -- 20
        c.CustomerID, c.CompanyName, c.Address, c.City,        -- 21
        c.Region,  c.PostalCode, c.Country, c.Phone,           -- 22
        p.ProductID, p.ProductName, p.UnitsInStock,            -- 23
        p.UnitsOnOrder                                         -- 24
 FROM   dbo.Orders o                                           -- 25
 JOIN   dbo.[Order Details] od ON o.OrderID = od.OrderID       -- 26
 JOIN   dbo.Customers c ON o.CustomerID = c.CustomerID         -- 27
 JOIN   dbo.Products p ON p.ProductID = od.ProductID           -- 28
     WHERE  1 = 1'                                             -- 29
                                                               -- 30
IF @orderid IS NOT NULL                                        -- 31
   SELECT @sql = @sql + ' AND o.OrderID = @xorderid' +         -- 32
                        ' AND od.OrderID = @xorderid'          -- 33
                                                               -- 34
IF @fromdate IS NOT NULL                                       -- 35
   SELECT @sql = @sql + ' AND o.OrderDate >= @xfromdate'       -- 36

等...

因此,在构建动态sql语句时,如果必须为@sql变量只运行一个sp_executesql,则有意义。

但是,假设您已构建了@sql,并返回了要返回的已过滤记录,但您还需要返回COUNT条记录。

这样做的最佳方法是什么?

您是否必须声明另一个变量@sql_2,其构建几乎与@sql相同,但SELECT中的@sql_2语句会执行{{1}而不是SELECT COUNT(*)...

或者有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

将SQL语句串在一起,用分号分隔。下面是一个工作示例,它返回数据库中以字母“A”和计数开头的表。 首先是简单的版本。这将返回2个结果集,第二个是计数。

declare @findTables nvarchar(256)
set @findTables = N'A%'

declare @sql nvarchar(max)

set @sql = N'set nocount on; '+
'select * from sys.tables where name like '''+@findTables+''';'+
'select @@RowCount as [RowCount];';

execute sp_executesql @sql

现在是一个版本,在这个版本中,当你需要在以后的存储过程中使用它时,变量会被计数值。

declare @findTables nvarchar(256)
set @findTables = N'A%'

declare @sql nvarchar(max)
declare @ParmDefinition nvarchar(500);
declare @rowCount int

set @sql = N'set nocount on; 
select * from sys.tables where name like @findTablesParm;
select @rowCountParm = @@rowcount;
select @rowCountParm as [RowCount];';

SET @ParmDefinition = N'@findTablesParm nvarchar(256), 
    @rowCountParm int OUTPUT';

execute sp_executesql @sql, 
    @ParmDefinition, 
    @findTablesParm=@findTables, 
    @rowCountParm=@rowCount OUTPUT

在此运行之后,您应该看到2个结果集,第二个将包含RowCount,变量@rowCount也将包含行计数。