8

アプリケーションに属するテーブルを処理し、同じアプリケーションに属するテーブルに値を挿入するストアドプロシージャを作成しています(したがって、どちらのテーブルも修正できません)。

新しいレコードのみを処理し、どのレコードが処理されたかを覚えておく必要があります。このために、3番目の単純なテーブルを作成しました。

以下の表は、重要な詳細のみを残すために多くの列が削除されています。

ソーステーブル

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
)

ソーステーブルからターゲットテーブルの値に挿入しようとしていますが、ソーステーブルの主キーもトラッキングテーブルに挿入しています。

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_DETAILDETAIL.DET_DETAILが、エラーは同じです。

グループを使用するときに句のソーステーブルの値を使用することはできませんOUTPUTか、それともフォーマットにエラーがありますか?それが不可能な場合、処理した行を追跡する別の方法はありますか?

4

2 に答える 2

10

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
于 2013-03-25T11:56:59.127 に答える
1

この質問はほぼ1年前のものですが、出力から適切な列名を選択すると、提示したとおりに挿入を機能させることができます。

output句は、操作に応じて、挿入または削除された2つの可能な仮想テーブルのいずれかを提供します。更新操作は両方を提供します。挿入したばかりの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
于 2014-03-05T03:53:18.363 に答える