我正在编写一个存储过程来处理属于某个应用程序的表,并将值插入属于同一个应用程序的表中(所以我不能修改任何一个表)。
我必须只处理新记录并记住已经处理了哪些记录,为此我创建了第三个简单表。
下面的表格,删除了许多列,只留下重要的细节。
来源表
CREATE TABLE [dbo].[DETAIL](
[DET_NET] [float] NULL,
[DET_VAT] [float] NULL,
[DET_VATCODE] [varchar](4) NULL,
[DET_GROSS] [float] NULL,
[DET_DATE] [datetime] NULL,
[DET_PRIMARY] [float] NOT NULL
)
目标表
CREATE TABLE [dbo].[TRN_TEMP](
[TRN_TRAN_DATE] [datetime] NULL,
[TRN_DESCRIPTION] [varchar](20) NULL,
[TRN_PRIMARY] [int] NULL,
[TRN_AMT] [float] NULL
)
跟踪表
CREATE TABLE REGISTER(
LINE_ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED NOT NULL,
DET_PRIMARY_LINK FLOAT NOT NULL,
INS_DATE DATETIME NOT NULL
)
我试图从源表中插入Target表值,但也将源表的主键插入到跟踪表中。
INSERT INTO TRN_TEMP (TRN_TRAN_DATE, TRN_DESCRIPTION, TRN_AMT)
OUTPUT D.DET_PRIMARY, GETDATE() INTO REGISTER (DET_PRIMARY_LINK, INS_DATE)
SELECT D.DET_DATE, 'SOMETEXT', SUM(D.DET_NET)
FROM DETAIL D
LEFT JOIN REGISTER R ON D.DET_PRIMARY = R.DET_PRIMARY_LINK
WHERE <MY CONDITIONS> AND R.LINE_ID IS NULL -- TO REMOVE LINES ALREADY PROCESSED
GROUP BY D.DET_DATE
我看不到上面文本的问题,但是我收到错误“无法绑定多部分标识符'D.DET_PRIMARY'。”
我已经尝试了D.DET_DETAIL
和DETAIL.DET_DETAIL
,错误也是一样。
使用组时是否无法使用OUTPUT
子句中源表中的值,或者格式化中是否有错误?
如果不可能有另一种方法来跟踪我处理的哪条线?
答案 0 :(得分:7)
使用MERGE
代替INSERT
:
MERGE
INTO trn_temp d
USING (
SELECT D.DET_DATE, 'SOMETEXT' AS sometext, SUM(D.DET_NET) AS the_sum
...
) s
ON (1 = 0)
WHEN NOT MATCHED THEN
INSERT (TRN_TRAN_DATE, TRN_DESCRIPTION, TRN_AMT)
VALUES (det_date, sometext, the_sum)
OUTPUT s.*
<强>更新强>
要解决GROUP BY
问题,请使用以下命令:
DECLARE @tmp TABLE
(
det_primary INT NOT NULL PRIMARY KEY
)
MERGE
INTO register r
USING detail d
ON (r.det_primary_link = d.det_primary)
WHEN NOT MATCHED THEN
INSERT (det_primary_link, ins_date)
VALUES (det_primary, GETDATE())
OUTPUT d.det_primary
INTO @tmp;
INSERT
INTO trn_temp (trn_tran_date, trn_description, trn_amt)
OUTPUT INSERTED.*
SELECT det_date, 'sometext', SUM(det_net)
FROM @tmp t
JOIN detail d
ON d.det_primary = t.det_primary
GROUP BY
det_date
答案 1 :(得分:2)
我知道这个问题已有将近一年的历史了,但是如果您从OUTPUT中选择了正确的列名,那么您的插入可以正常工作
output子句为我们提供了两个可能的虚拟表之一,插入或删除,具体取决于操作,更新操作同时给出。由于您刚刚插入的TRN_TEMP表中没有字段名称DET_DATE,因此在输出语句中它无效。
INSERT INTO TRN_TEMP (TRN_TRAN_DATE, TRN_DESCRIPTION, TRN_AMT)
OUTPUT INSERTED.TRN_TRAN_DATE, GETDATE()
INTO REGISTER (DET_PRIMARY_LINK, INS_DATE)
SELECT D.DET_DATE, 'SOMETEXT', SUM(D.DET_NET)
FROM DETAIL D
LEFT JOIN REGISTER R ON D.DET_PRIMARY = R.DET_PRIMARY_LINK
WHERE <MY CONDITIONS> AND R.LINE_ID IS NULL -- TO REMOVE LINES ALREADY PROCESSED
GROUP BY D.DET_DATE