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

时间:2011-02-06 01:21:25

标签: sql-server tsql

第2部分:在他的文章“T-SQL中的动态搜索条件... for 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

等...

在dyanmic sql的另一个article中,他写道:

  

在动态SQL中创建的临时表将无法从调用过程访问,因为它们在动态SQL退出时被删除。

所以我的问题围绕着这个问题:如果你已经构建了动态sql 语句一次,@sql中的SELECT语句返回col1,col2,col3,col4等, 如果您必须以不同方式重新查询相同的结果集,该怎么办?例如,如果您必须返回另一个具有COUNT并按col1分组的结果集, 另一个结果集,其COUNT按col2分组,或其他一些标准,其基础是原始@sql的结果集?

你是否必须为每个不同的场景重新构建@sql, 所以你最终得到@ sql,@ sql_2,@ sql_3,...?

在这种情况下,动态sql仍然是最好的选择,还是会 最好使用插入到#temp表中的静态sql,这样就可以了 重新查询#temp表的结果?

3 个答案:

答案 0 :(得分:0)

好的,这是一个关于msdn网站上这个问题的解决方案的例子。

http://social.msdn.microsoft.com/Forums/en/sqlreportingservices/thread/3ed6885a-fe18-41c0-bce4-76c44c737a1b

问题是:如果你创建临时表,并在动态sql中创建临时表,则无法访问动态sql的临时表OUTSIDE。 但是,如果您首先创建动态sql的临时表OUTSIDE, 然后填充临时表INSIDE的动态sql,可以访问动态sql的填充临时表OUTSIDE。

答案 1 :(得分:0)

另一种方法是使用INSERT ... EXEC设备,但使用方式比您自己的查找更有限。

INSERT INTO sometable    /* or @vartable or #temptable */
EXEC sp_executesql @sql  /* and @params, if needed */

您不能在另一个INSERT...EXEC中调用本身的SP中使用它。

答案 2 :(得分:0)

在 SQL Server 中,如果您在动态 SQL 中创建临时表,则无法从调用过程中的非动态 SQL 访问该临时表。正如你所说。

您有几个选择:

  • 事先创建临时表(在非动态 sql 中)。然后可以从动态 sql 中使用它,以便您可以插入其中。
  • 如果您不知道临时表结构,那么上一个选项似乎没有那么有用。但是您可以先使用单个虚拟列创建临时表,然后从动态 sql 修改临时表的结构。看起来有点恶心,但有时很方便。
  • 使用 ## 全局临时表
  • 使用真实表格,或许使用“批处理”标识符将您的结果与其他人的结果也插入真实表格中的结果分开。
  • 使用动态 SQL 创建/更改一个过程,该过程以您想要的方式创建临时表。然后您可以从非动态 SQL 调用该过程。相当多的工作,但有时很方便。
  • 按照您在问题中的建议,以不同方式重建动态 sql,并分别执行它们。性能不如您要多次处理数据,但通常这并不重要。