2

親子関係にいくつかの行を挿入しようとしています。SQLでこれをどのように達成しますか?

これは、挿入する情報を見つけるために使用する基本クエリになります。

SELECT * FROM parentTable p
INNER JOIN childTable c
    ON p.ID = c.ParentTableID
WHERE p.PlanID = 123456

必要なのは、最初に ParentTable 行を挿入することです。これは、実際には一致した行の単なるコピーですが、新しい PlanID と Created Date が含まれています。次に、挿入された行からその ParentTable ID を取得し、それを同じプロセスで子テーブルに使用します。

したがって、.Net で行う必要があるのは、少なくとも、parentTable のすべての一致をループし、一致ごとに 1 つの childTable 行を作成する場所です。

節を使おうとしMERGEたのOUTPUTですが、丸穴に四角いペグを使っているようです。ある種の CURSOR を使用したほうがよいでしょうか?


これは、以下の回答に基づいて、これまでのところ私が持っているものです。残念ながら、それはつかんでいませんSCOPE_IDENTITY()...それにはトリックはありますか?NULL を返すため、挿入時に FK エラーが発生します。

USE MemberCenteredPlan

DECLARE @NewPlanID BIGINT;--49727690
DECLARE @OldPlanID BIGINT;--49725211
DECLARE @NewSWReAssID BIGINT;

SET @NewPlanID = 49727690
SET @OldPlanID = 49725211

BEGIN
INSERT INTO tblSocialWorkerReAssessment 
SELECT 
    @NewPlanID
    ,[Discussed]
    ,Discussion
    ,NULL
    ,NULL
    ,NULL   
    ,CreatedBy
    ,GETDATE()
    ,NULL
    ,NULL
    FROM tblSocialWorkerReAssessment
    WHERE PlanID = @OldPlanID

SELECT @NewSWReAssID = SCOPE_IDENTITY();

INSERT INTO tblPlanDomain
SELECT 
   @NewPlanID
   ,[DomainTypeID]
   ,[MemberOutcomes]
   ,[MemberPreferences]
   ,[DomainDate]
   ,[Steps]
    ,[ClinicalFunctionalConcerns]
    ,[ReportWageES]
    ,[ReportWageSSA]
    ,@NewSWReAssID
    ,[CreatedBy]
   ,GETDATE()
   ,NULL
   ,NULL   
   ,NEWID()
FROM tblPlanDomain 
WHERE planID = @OldPlanID

END
4

2 に答える 2

4

MERGEカーソルは必要ありませんし、絶対に必要ありません。また、INSERT(またはMERGE) は一度に 1 つのテーブルにしか影響を与えないため、とにかく複数のステートメントを実行する必要があります。一度に 1 つのプランしか処理しない場合は、次のようにすることができます。

DECLARE @NewPlanID INT;

INSERT dbo.ParentTable(cols...) 
  SELECT cols...
  FROM dbo.ParentTable WHERE PlanID = 123456;

SELECT @NewPlanID = SCOPE_IDENTITY();

INSERT dbo.ChildTable(ParentTableID, cols...) 
  SELECT @NewPlanID, cols...
  FROM dbo.ChildTable WHERE PlanID = 123456;

複数の新しいプランを参照する必要がある場合は、もう少し複雑になりMERGEますINSERT。表中OUTPUT)。

DECLARE @p TABLE(OldPlanID INT, NewPlanID INT);

MERGE dbo.ParentTable WITH (HOLDLOCK)
USING 
(
  SELECT ID, cols... FROM dbo.ParentTable 
  WHERE ID IN (123456, 234567)
) AS src ON src.ID IS NULL
WHEN NOT MATCHED THEN INSERT(cols...)
VALUES(src.cols...)
OUTPUT src.ID, inserted.ID INTO @p;

INSERT dbo.ChildTable(ParentTableID, cols...)
SELECT p.NewPlanID, t.cols... 
FROM dbo.ChildTable AS t
INNER JOIN @p AS p
ON t.ParentTableID = p.OldPlanID;

ただし、これには非常に注意する必要があります... dba.SEMERGEのこの回答で、いくつかの問題と未解決のバグにリンクしています。私はまた、ここに警告のヒントを投稿しましたが、他の何人かは同意しています。

于 2013-08-26T18:01:30.233 に答える