【问题标题】:TSQL Writing into a Temporary Table from Dynamic SQLTSQL 从动态 SQL 写入临时表
【发布时间】:2009-03-27 01:16:33
【问题描述】:

考虑以下代码:

SET @SQL1 = 'SELECT * INTO #temp WHERE ...'
exec(@SQL1)
SELECT * from #temp  (this line throws an error that #temp doesn't exist)

显然这是因为 exec 命令衍生出一个单独的会话,而 #temp 是该会话的本地。我可以使用全局临时表##temp,但是我必须想出一个命名方案以避免冲突。大家有什么推荐的?

【问题讨论】:

    标签: sql-server tsql session temp-tables


    【解决方案1】:

    试试##temp 因为您的动态查询是在另一根光纤上执行的 所以你看不到它的本地临时表。 相反,如果您将临时表声明为 global 则有意义。

    【讨论】:

      【解决方案2】:

      您是否尝试显式创建模板表?

      Create Table #temp (..)
      

      【讨论】:

      • 这确实解决了范围界定问题。但是,由于在执行 exec 语句之前我不知道架构。 (除非有办法在不定义模式的情况下创建表?)
      • # 告诉您您正在使用 tempdb,并自动解析为 tempdb 中具有巨大旧随机名称的实际表,从而防止冲突。您不需要架构名称来发出创建语句,但您应该在动态 SQL 之外执行它。
      【解决方案3】:

      您可以在 exec 之前创建 temp 并使用 exec 填充 temp 表。

      【讨论】:

      • 如何在不知道架构的情况下创建临时表? (我的 select into 定义了架构)
      【解决方案4】:

      没有找到可以满足我所有需求的可行解决方案,因此我改用 ##global 临时表。

      【讨论】:

      • 多用户环境下可能会出现问题
      • @Madhivanan 有什么问题?
      【解决方案5】:

      举个例子,看“成”

      SELECT o.OrderID, o.OrderDate, od.UnitPrice, od.Quantity,
             c.CustomerID, c.CompanyName, c.Address, c.City, c.Region,
             c.PostalCode, c.Country, c.Phone, p.ProductID,
             p.ProductName, p.UnitsInStock, p.UnitsOnOrder
      INTO   #temp
      FROM   Orders o
      JOIN   [Order Details] od ON o.OrderID = od.OrderID
      JOIN   Customers c ON o.CustomerID = c.CustomerID
      JOIN   Products p ON p.ProductID = od.ProductID
      

      【讨论】:

        【解决方案6】:

        你能不能把你的选择放在插入后用 ;分隔符并将两个语句一起运行?

        【讨论】:

          【解决方案7】:

          另一种方法是使用动态SQL中的所有代码

          SET @SQL1 = 'SELECT * INTO #temp WHERE ...
          SELECT * from #temp  ' 
          exec(@SQL1) 
          

          【讨论】:

            【解决方案8】:

            有一种方法可以创建具有单个标识列的 dummy 临时表,然后通过动态 SQL 以所需的模式更改该表并填充它。这样您就可以在动态和常规 SQL 中使用临时表,加入它...

            -- Create dummy table
            CREATE TABLE #tmpContactData (PK int NOT NULL IDENTITY(1,1))
            
            -- Alter its schema
            DECLARE @sqlCommand nvarchar(max)
            SELECT @sqlCommand = '
            ALTER TABLE #tmpContactData
            ADD 
                EmployeeId int,
                Address varchar(100),
                Phone varchar(50)
            '
            EXECUTE(@sqlCommand)
            
            -- Fill it
            SELECT @sqlCommand = '
            INSERT INTO #tmpContactData
            SELECT t.EmployeeId, t.Address, t.Phone 
            FROM (  SELECT EmployeeId=1000, Address=''Address 1000'', Phone=''Phone 1000'' 
                    UNION 
                    SELECT 1001, ''Address 1001'', ''Phone 1001'' 
                    UNION 
                    SELECT 1002, ''Address 1002'', ''Phone 1002''
            ) t
            '
            EXECUTE(@sqlCommand)
            
            --select from it
            SELECT * FROM #tmpContactData
            
            --CleanUp
            DROP TABLE #tmpContactData
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2018-04-29
              • 1970-01-01
              • 2017-09-17
              • 2011-02-24
              • 1970-01-01
              • 2014-01-17
              • 1970-01-01
              • 2012-03-21
              相关资源
              最近更新 更多