3

こんにちは、現在、select ステートメントの結果に基づいてレコードを挿入および削除する SP を作成しています。

これは私のサンプルコードです:

DECLARE @PickListBatchName varchar(200),
@PartNumber varchar(50),
@QTY int;

SET @PickListBatchName='TEST1';
SET @PartNumber='PN1';
SET @QTY=1;


      --STEP 1 Add Result to TempTable
      With SN as
      (
        SELECT TOP (@QTY) 
           pb.PickListBatchId
           ,pt.PickListTRANId
           ,pt.SerialNumber
           ,pt.Createdby
           ,pt.CreatedDT
FROM PickListTRAN pt 
            LEFT JOIN PickListBatchDetail pdb ON pdb.PickListBatchDetailId=pt.PickListBatchDetailId
            LEFT JOIN PickListBatch pb ON pdb.PickListBatchId=pb.PickListBatchId
where  pb.PickListBatchName=@PickListBatchName AND pdb.PartNumber=@PartNumber
      )


    --STEP 2: INSERT SN TO PicklistTranCancel
    INSERT INTO PickListTRANCancel
   (
   PickListBatchId
   ,SerialNumber
   ,CreatedBy
   ,CreatedDT
   ) 
   (SELECT  
           PickListBatchId,
           SerialNumber,
           Createdby,
           CreatedDT
    FROM SN);

    --STEP 3: DELETE Records on PicklistTran

    DELETE FROM PicklistTran where picklistTranId IN (SELECT PickListTRANId FROM SN)

結果:

(1 row(s) affected)
Msg 208, Level 16, State 1, Line 49
Invalid object name 'SN'.  --error on delete statement

ステップ 3 で、delete ステートメントは SN テーブルを読み取ることができません。多分私はその部分に何かが欠けています。

よろしくお願いします

4

4 に答える 4

6

あなたのコードでは、 CTE は insert statement までしかアクセスできません。CTE テーブルにアクセスする必要がある場合は、CTE データを @TempTable に入力してから、delete ステートメントでアクセスしてみてください。値を一時テーブルに保存するようにコードを変更できます。

 INSERT INTO PickListTRANCancel

  (
  PickListBatchId
  ,SerialNumber
  ,CreatedBy
  ,CreatedDT
  ) 
Output   Inserted.PickListBatchId,Inserted.SerialNumber,Inserted.CreatedBy,
Inserted.CreatedDT into @TempTable
  (SELECT  
       PickListBatchId,
       SerialNumber,
       Createdby,
       CreatedDT
FROM SN);

   DELETE FROM PicklistTran where picklistTranId IN
   (SELECT PickListTRANId FROM @TempTable)

コードを確認していませんが、この方法でクエリを組み立てることができます。

于 2012-06-06T07:56:09.670 に答える
2

CTE は、単一の SELECT、INSERT、UPDATE、DELETE、MERGE、または CREATE VIEW ステートメントの実行範囲内で定義される一時的な結果セットです。- http://msdn.microsoft.com/en-us/library/ms190766(v=sql.105).aspx

上記のように、CTE は 1 つのステートメントでのみ使用できるため、2 番目のステートメントでは使用できなくなりました。

于 2012-06-06T07:56:48.383 に答える
1

@benni_mac_b と @praveen に感謝します。WITH を使用する代わりに、TempTable を作成するために使用します。

DECLARE @PickListBatchName varchar(200),
@PartNumber varchar(50),
@QTY int;

SET @PickListBatchName='TEST1';
SET @PartNumber='PN1';
SET @QTY=1;

Declare @MyTable table 
(
     PickListBatchId int,
     PickListTRANId int,
    SerialNumber varchar(50),
    Createdby varchar(50),
    CreatedDT datetime
);


 --STEP 1: insert to temptable 
 INSERT INTO @MyTable
                    (
           PickListBatchId,
           PickListTRANId,
           SerialNumber,
           Createdby,
           CreatedDT
                    )
SELECT TOP (@QTY) 
           pb.PickListBatchId
           ,pt.PickListTRANId
           ,pt.SerialNumber
           ,pt.Createdby
           ,pt.CreatedDT
FROM PickListTRAN pt 
            LEFT JOIN PickListBatchDetail pdb ON pdb.PickListBatchDetailId=pt.PickListBatchDetailId
            LEFT JOIN PickListBatch pb ON pdb.PickListBatchId=pb.PickListBatchId
where  pb.PickListBatchName=@PickListBatchName AND pdb.PartNumber=@PartNumber


    --STEP 2: INSERT SN TO PicklistTranCancel
    INSERT INTO PickListTRANCancel
   (
   PickListBatchId
   ,SerialNumber
   ,CreatedBy
   ,CreatedDT
   ) 
   SELECT  
   PickListBatchId,
   SerialNumber,
   Createdby,
   CreatedDT
   FROM @MyTable

   --STEP 3: DELETE
   DELETE FROM PicklistTran where picklistTranId IN (SELECT PickListTRANId FROM @MyTable)
于 2012-06-06T08:17:37.767 に答える
0

CTEスコープは1つのステートメントでのみ使用可能であり、2回使用することはできません。一時テーブルを使用してCTEの値を保存できます

于 2012-06-06T09:07:09.697 に答える