185

我有一个非常复杂的 CTE,我想将结果插入到物理表中。

以下内容有效吗?

INSERT INTO dbo.prf_BatchItemAdditionalAPartyNos 
(
    BatchID,
    AccountNo,
    APartyNo,
    SourceRowID
)       
WITH tab (
  -- some query
)    
SELECT * FROM tab

我正在考虑使用一个函数来创建这个允许我重用的 CTE。有什么想法吗?

4

4 回答 4

320

您需要先放置 CTE,然后将 INSERT INTO 与您的 select 语句结合起来。此外,CTE 名称后面的“AS”关键字不是可选的:

WITH tab AS (
    bla bla
)
INSERT INTO dbo.prf_BatchItemAdditionalAPartyNos (
BatchID,
AccountNo,
APartyNo,
SourceRowID
)  
SELECT * FROM tab

请注意,代码假定 CTE 将准确返回四个字段,并且这些字段的顺序和类型与 INSERT 语句中指定的字段匹配。如果不是这种情况,只需将“SELECT *”替换为您需要的特定字段选择。

至于你关于使用函数的问题,我会说“这取决于”。如果您只是出于性能原因将数据放入表中,并且通过函数使用它时速度是可以接受的,那么我会考虑使用函数。另一方面,如果您需要在几个不同的查询中使用 CTE 的结果,并且速度已经是一个问题,我会选择一个表(常规的或临时的)。

WITH common_table_expression (Transact-SQL)

于 2010-07-22T05:54:27.420 回答
31

公共表表达式的WITH子句位于顶部。

将每个插入包装在 CTE 中具有将查询逻辑与列映射直观隔离的好处。

发现错误:

WITH _INSERT_ AS (
  SELECT
    [BatchID]      = blah
   ,[APartyNo]     = blahblah
   ,[SourceRowID]  = blahblahblah
  FROM Table1 AS t1
)
INSERT Table2
      ([BatchID], [SourceRowID], [APartyNo])
SELECT [BatchID], [APartyNo], [SourceRowID]   
FROM _INSERT_

同样的错误:

INSERT Table2 (
  [BatchID]
 ,[SourceRowID]
 ,[APartyNo]
)
SELECT
  [BatchID]      = blah
 ,[APartyNo]     = blahblah
 ,[SourceRowID]  = blahblahblah
FROM Table1 AS t1

几行样板代码使得验证代码以正确的顺序插入正确数量的列变得非常容易,即使是非常多的列。你未来的自己会在以后感谢你。

于 2015-05-08T20:49:11.777 回答
18

是的:

WITH tab (
  bla bla
)

INSERT INTO dbo.prf_BatchItemAdditionalAPartyNos (  BatchID,                                                        AccountNo,
APartyNo,
SourceRowID)    

SELECT * FROM tab

请注意,这是针对支持多个 CTE 的 SQL Server:

WITH x AS (), y AS () INSERT INTO z (a, b, c) SELECT a, b, c FROM y

Teradata 只允许一个 CTE,语法就是您的示例。

于 2010-07-22T05:52:27.923 回答
0

在这里聚会迟到了,但出于我的目的,我希望能够运行用户输入的代码并将其存储在临时表中。使用 oracle 没有这样的问题.. 插入在 with 子句之前的语句开头。

为此,在 sql server 中工作,以下工作:

插入到#stagetable 执行(@InputSql)

(因此选择语句 @inputsql 可以作为 with 子句开始)。

于 2021-04-20T17:49:08.793 回答