结合INSERT INTO和WITH/CTE

dcp*_*ers 148 t-sql insert common-table-expression

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

以下是否有效?

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

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

Val*_*ken 255

您需要先放置CTE,然后将INSERT INTO与select语句结合使用.此外,CTE名称后面的"AS"关键字不是可选的:

WITH tab AS (
    bla bla
)
INSERT INTO dbo.prf_BatchItemAdditionalAPartyNos (
BatchID,
AccountNo,
APartyNo,
SourceRowID
)  
SELECT * FROM tab
Run Code Online (Sandbox Code Playgroud)

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

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

WITH common_table_expression(Transact-SQL)


Cad*_*oux 16

是的:

WITH tab (
  bla bla
)

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

SELECT * FROM tab
Run Code Online (Sandbox Code Playgroud)

请注意,这适用于支持多个CTE的SQL Server:

WITH x AS (), y AS () INSERT INTO z (a, b, c) SELECT a, b, c FROM y
Run Code Online (Sandbox Code Playgroud)

Teradata只允许一个CTE,语法就是你的例子.


Ano*_*non 16

WITHCommon Table Expressions 的子句位于顶部.

包装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_
Run Code Online (Sandbox Code Playgroud)

同样的错误:

INSERT Table2 (
  [BatchID]
 ,[SourceRowID]
 ,[APartyNo]
)
SELECT
  [BatchID]      = blah
 ,[APartyNo]     = blahblah
 ,[SourceRowID]  = blahblahblah
FROM Table1 AS t1
Run Code Online (Sandbox Code Playgroud)

几行样板文件可以非常轻松地验证代码是否以正确的顺序插入正确数量的列,即使列数非常多.你未来的自我会在以后感谢你.

  • 这很棒!突然之间,我并不讨厌INSERT语句...... (3认同)
  • 这非常有用。对于第一次阅读时错过的人来说,它解决的问题是,在插入语句中,映射是由要插入的字段和要插入其中的值的相对顺序定义的,这些字段是单独列出的。如果您正常编写这些内容,则很难通过目视检查来检查这两个顺序是否相同。CTE 允许您使用要插入的列名称来命名值,这意味着您可以将这些值很好地对齐在两行上。 (3认同)