Kết hợp INSERT INTO và VỚI / CTE


157

Tôi có một CTE rất phức tạp và tôi muốn chèn kết quả vào một bảng vật lý.

Là sau đây hợp lệ?

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

Tôi đang nghĩ đến việc sử dụng một chức năng để tạo CTE này cho phép tôi sử dụng lại. Có suy nghĩ gì không?

Câu trả lời:


270

Bạn cần đặt CTE trước và sau đó kết hợp INSERT INTO với câu lệnh chọn của bạn. Ngoài ra, từ khóa "NHƯ" theo tên của CTE không phải là tùy chọn:

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

Xin lưu ý rằng mã giả định rằng CTE sẽ trả về chính xác bốn trường và các trường đó khớp với thứ tự và loại với các trường được chỉ định trong câu lệnh INSERT. Nếu đó không phải là trường hợp, chỉ cần thay thế "CHỌN *" bằng một lựa chọn cụ thể của các trường mà bạn yêu cầu.

Đối với câu hỏi của bạn về việc sử dụng một chức năng, tôi sẽ nói "nó phụ thuộc". Nếu bạn đặt dữ liệu vào một bảng chỉ vì lý do hiệu suất và tốc độ có thể chấp nhận được khi sử dụng nó thông qua một chức năng, thì tôi sẽ coi chức năng là một tùy chọn. Mặt khác, nếu bạn cần sử dụng kết quả của CTE trong một số truy vấn khác nhau và tốc độ đã là một vấn đề, tôi sẽ tìm một bảng (thông thường hoặc tạm thời).

VỚI common_table_expression (Transact-SQL)


19

Các WITHkhoản cho Common Table Expressions đi ở đầu trang.

Việc bao bọc mọi chèn trong CTE có lợi ích là phân tách trực quan logic truy vấn khỏi ánh xạ cột.

Phát hiện lỗi:

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_

Lỗi tương tự:

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

Một vài dòng soạn sẵn giúp việc xác minh mã chèn đúng số cột theo đúng thứ tự, ngay cả với số lượng cột rất lớn. Tương lai của bạn sẽ cảm ơn bạn sau này.


3
Điều đó thật tuyệt! Thật bất ngờ, tôi không ghét những tuyên bố của INSERT nhiều ...
NRzingh

1
Điều này là vô cùng hữu ích. Đối với bất kỳ ai khác đã bỏ lỡ nó trong lần đọc đầu tiên, vấn đề này giải quyết là trong một câu lệnh chèn, ánh xạ được xác định theo thứ tự tương đối của các trường được chèn vào và các giá trị được chèn vào chúng, được liệt kê riêng. Nếu bạn viết những thứ này một cách bình thường thì rất khó kiểm tra bằng cách kiểm tra trực quan rằng hai thứ tự giống nhau. CTE cho phép bạn đặt tên cho các giá trị bằng tên cột mà chúng sẽ được chèn vào, điều đó có nghĩa là bạn có thể căn chỉnh các giá trị này thực sự độc đáo trên hai dòng.
Tidorith

16

Vâng:

WITH tab (
  bla bla
)

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

SELECT * FROM tab

Lưu ý rằng đây là dành cho SQL Server, hỗ trợ nhiều CTE:

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

Teradata chỉ cho phép một CTE và cú pháp là ví dụ của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.