2016-04-11 16 views
0

私はSQL Serverを初めて使い、電話リンクテーブルのレコードを複製するためにカーソルを使用する必要があるタスクを与えられました。他のテーブル私はカーソルを使用することなく複製することができました。しかし私は電話リンクテーブルにプライマリキーの制約があります。誰かが私を助けてくれますか?ありがとうございました。以下は私のストアドプロシージャです。インテークパラメータはcomp_companyidです。私の要件は、すべての列を同じテーブルに複製し、新しい主キー&外部キーを生成することです。SQL Server:ストアドプロシージャ内にカーソルを挿入

P/S:

  • 実体識別子= 5(社)
  • 実体識別子= 13(人)

私もその後に追加する人の電話&者の電話回線を持っていると。しかし、私はこれを最初に解決する必要がありますし、私は人の電話をしているときこれを参照することができます。

また、1つの会社は複数の人物、住所を持つことができます。

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[DuplicateCompanyInfo] 
    @Comp_CompanyId NVARCHAR(80) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @CompanyID NVARCHAR(30), 
      @PersonID NVARCHAR(30), 
      @PersonLinkID NVARCHAR(30), 
      @AddressLinkID NVARCHAR(30), 
      @AddressID NVARCHAR(30), 
      @PhoneLinkID NVARCHAR(30), 
      @PhoneID NVARCHAR(30) 

    EXEC @companyId = crm_next_id 5 
    EXEC @PersonId = crm_next_id 13 
    EXEC @PersonLinkId = crm_next_id 31 
    EXEC @AddressLinkId = crm_next_id 21 
    EXEC @AddressId = crm_next_id 1 
    EXEC @PhoneLinkId = crm_next_id 10208 
    EXEC @PhoneId = crm_next_id 14 

    -- Add Company 
    INSERT INTO Company 
    (
     Comp_CompanyId, Comp_PrimaryPersonId, Comp_PrimaryAddressId, Comp_Name, Comp_Type, Comp_Status, Comp_CreatedBy, 
     Comp_CreatedDate, Comp_UpdatedBy, Comp_UpdatedDate, Comp_TimeStamp, Comp_SecTerr, Comp_WebSite 
    ) 
     SELECT 
      @companyId, @PersonId, @AddressId, Comp_Name, Comp_Type, 
      Comp_Status, Comp_CreatedBy, 
      Comp_CreatedDate, '1', GETDATE(), Comp_TimeStamp, 
      Comp_SecTerr, Comp_WebSite 
     FROM 
      Company 
     WHERE 
      Comp_CompanyId = @comp_companyid 

    -- Add Person_Link Without Type 
    INSERT INTO Person_Link 
    (
     PeLi_PersonLinkId, PeLi_PersonId, PeLi_CompanyID, PeLi_CreatedBy, PeLi_CreatedDate, PeLi_UpdatedBy, 
     PeLi_UpdatedDate, PeLi_TimeStamp 
    ) 
     SELECT 
      @PersonLinkId, @PersonId, @CompanyId, PeLi_CreatedBy, 
      PeLi_CreatedDate, '1', GETDATE(), PeLi_TimeStamp 
     FROM 
      Person_Link 
     WHERE 
      PeLi_CompanyID = @comp_companyid 

    -- Add Person 
    INSERT INTO Person 
    (
     Pers_PersonId, Pers_CompanyId, Pers_PrimaryUserId, Pers_FirstName, pers_SecTerr, Pers_CreatedBy, 
     Pers_CreatedDate, Pers_UpdatedBy, Pers_UpdatedDate, Pers_TimeStamp 
    ) 
     SELECT 
      @PersonId, @companyId, Pers_PrimaryUserId, Pers_FirstName, 
      pers_SecTerr, Pers_CreatedBy, 
      Pers_CreatedDate, '1', GETDATE(), Pers_TimeStamp 
     FROM 
      Person 
     WHERE 
      Pers_CompanyId = @comp_companyid 

    -- Add Address_Link 
    INSERT INTO Address_Link 
    (
     AdLi_AddressLinkId, AdLi_AddressId, AdLi_CompanyID, AdLi_CreatedBy, AdLi_CreatedDate, 
     AdLi_UpdatedBy, AdLi_UpdatedDate, AdLi_TimeStamp, AdLi_Type 
    ) 
     SELECT 
      @AddressLinkId, @AddressId, @companyId, AdLi_CreatedBy, 
      AdLi_CreatedDate, '1', GETDATE(), AdLi_TimeStamp, AdLi_Type 
     FROM 
      Address_Link 
     WHERE 
      AdLi_CompanyID = @comp_companyid 


    -- Add Address 
    INSERT INTO [Address] 
    (
     Addr_AddressId, Addr_Address1, Addr_Address2, Addr_Address3, Addr_Address4, addr_postcode, 
     Addr_CreatedBy, Addr_CreatedDate, Addr_UpdatedBy, Addr_UpdatedDate, Addr_TimeStamp 
    ) 
    SELECT @AddressId, Addr_Address1, Addr_Address2, Addr_Address3, Addr_Address4, addr_postcode, 
      Addr_CreatedBy, Addr_CreatedDate, '1', GETDATE(), Addr_TimeStamp 
    FROM Address 
    INNER JOIN Address_Link 
    ON Addr_AddressId = AdLi_AddressId 
    AND AdLi_CompanyID = @comp_companyid 



    -- Add PhoneLink 
    -- Declare Variables 


    DECLARE @c_PLink_LinkID NVARCHAR(30) 
    DECLARE @c_PLink_PhoneId NVARCHAR(30) 
    DECLARE @c_PLink_CreatedBy NVARCHAR(30) 
    DECLARE @c_PLink_CreatedDate NVARCHAR(30) 
    DECLARE @c_PLink_UpdatedDate NVARCHAR(30) 
    DECLARE @c_PLink_TimeStamp NVARCHAR(30) 
    DECLARE @c_PLink_EntityID NVARCHAR(30) 
    DECLARE @c_PLink_RecordID NVARCHAR(30) 
    DECLARE @c_PLink_Type NVARCHAR(30) 
    DECLARE @c_Phon_PhoneId NVARCHAR(30) 

     EXEC @c_PLink_LinkID = crm_next_id 10208 
     EXEC @c_PLink_PhoneId = crm_next_id 14 


    --Declare Cursor 
    DECLARE @getPLID CURSOR 
    SET @getPLID= CURSOR FOR 
    SELECT PLink_LinkID, PLink_PhoneId, PLink_CreatedBy, PLink_CreatedDate, PLink_UpdatedDate, PLink_TimeStamp, 
    PLink_EntityID, PLink_RecordID, PLink_Type 
    FROM PhoneLink 
    WHERE PLink_EntityID = 5 
    AND PLink_RecordID = @Comp_CompanyId 

    --Open Cursor & fetch 1st row into variables 
    OPEN @getPLID 
    FETCH NEXT FROM @getPLID INTO @c_PLink_LinkID, @c_PLink_PhoneId, @c_PLink_CreatedBy, 
    @c_PLink_CreatedDate, @c_PLink_UpdatedDate, @c_PLink_TimeStamp, @c_PLink_EntityID, @c_PLink_RecordID, @c_PLink_Type 

    --Check for a new row 
    WHILE @@FETCH_STATUS = 0 
    BEGIN 

     INSERT INTO PhoneLink 
     (
      PLink_LinkID, PLink_PhoneId, PLink_CreatedBy, PLink_CreatedDate, PLink_UpdatedDate, PLink_TimeStamp, 
      PLink_EntityID, PLink_RecordID, PLink_Type 
     ) 

     VALUES 
     (
      @c_PLink_LinkID, @c_PLink_PhoneId, @c_PLink_CreatedBy, @c_PLink_CreatedDate, @c_PLink_UpdatedDate, @c_PLink_TimeStamp, 
      @c_PLink_EntityID, @c_PLink_RecordID, @c_PLink_Type 
     ) 


    --Get next available row into variables 
    FETCH NEXT FROM @getPLID INTO @c_PLink_LinkID, @c_PLink_PhoneId, @c_PLink_CreatedBy, 
    @c_PLink_CreatedDate, @c_PLink_UpdatedDate, @c_PLink_TimeStamp, @c_PLink_EntityID, @c_PLink_RecordID, @c_PLink_Type 

    END 

    CLOSE @getPLID 
    DEALLOCATE @getPLID 



    -- Add Company Phone 
    INSERT INTO Phone 
    (
     Phon_PhoneId, Phon_Number, Phon_CreatedBy, Phon_CreatedDate, Phon_UpdatedBy, Phon_UpdatedDate, Phon_TimeStamp 
    ) 
    SELECT @PhoneID, Phon_Number, Phon_CreatedBy, Phon_CreatedDate, '1', GETDATE(), Phon_TimeStamp 
    FROM Phone 
    INNER JOIN PhoneLink 
    ON Phon_PhoneId = PLink_PhoneId 
    AND PLink_EntityID = 5 
    AND PLink_RecordID = @Comp_CompanyId 


END 

私が間違っていた部分を教えていただければ幸いです。事前に時間と労力をいただきありがとうございます!

+0

PhoneLinkテーブルの主キーは何ですか? –

+0

@ダンそれはPLink_LinkID –

+0

なぜすべてのIDがvarcharですか? –

答えて

0

挿入された列の意味はわかりませんが、多くの行を挿入する場合、各行に別の一意のIDを生成する必要があります。したがって、ID生成コードをカーソル宣言の前に置くのではなく、カーソル本体に移動して、このジェネレータを各繰り返しとして呼び出す必要があります。

... 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    EXEC @c_PLink_LinkID = crm_next_id 10208 
    EXEC @c_PLink_PhoneId = crm_next_id 14 

    INSERT INTO PhoneLink 
    (
     PLink_LinkID, PLink_PhoneId, PLink_CreatedBy, PLink_CreatedDate, PLink_UpdatedDate, PLink_TimeStamp, 
     PLink_EntityID, PLink_RecordID, PLink_Type 
    ) 

    VALUES 
    (
     @c_PLink_LinkID, @c_PLink_PhoneId, @c_PLink_CreatedBy, @c_PLink_CreatedDate, @c_PLink_UpdatedDate, @c_PLink_TimeStamp, 
     @c_PLink_EntityID, @c_PLink_RecordID, @c_PLink_Type 
    ) 


    FETCH NEXT FROM @getPLID 
    INTO @c_PLink_CreatedBy, @c_PLink_CreatedDate, @c_PLink_UpdatedDate, 
     @c_PLink_TimeStamp, @c_PLink_EntityID, @c_PLink_RecordID, @c_PLink_Type 
END 

PhoneIDも生成する必要がある場合は、カーソル内に配置する必要があります。 また、元の値が必要ないので、カーソルの選択からPLink_LinkIDとPLink_PhoneIdを削除してください。そして、もちろん、フェッチリストからremove'em。上記のとおりです。

しかし、
私の前提が正しければ、あなたは少し間違った方向に行きます。 PhoneLinkテーブルが、新しく作成されたEntity/Companyにいくつかの電話機をリンクするテーブルである場合、Phone_IDと新しいCompany_IDとの間のリンクを構築するためにPhone Firstをコピーしてから(そのレコードのIDを生成する) 会社ごとに電話が1つしかない場合(ちょっと変わってしまいます)、カーソルは必要ありません。しかし、企業ごとに複数の電話機を設置できる場合は、新しいPhone_IDをいくつか生成する必要があります。つまり、反復リンクの代わりに電話のリンクを繰り返す必要があります。コードは次のようになりますと:

... 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    EXEC @c_PLink_LinkID = crm_next_id 10208 
    EXEC @c_PLink_PhoneId = crm_next_id 14 

    INSERT INTO Phone 
    (
     Phon_PhoneId, Phon_Number, Phon_CreatedBy, Phon_CreatedDate, Phon_UpdatedBy, Phon_UpdatedDate, Phon_TimeStamp 
    ) 
     SELECT @PhoneID, Phon_Number, Phon_CreatedBy, Phon_CreatedDate, '1', GETDATE(), Phon_TimeStamp 
     FROM Phone 
     WHERE Phon_PhoneId = @Old_Phone_ID 

    INSERT INTO PhoneLink 
    (
     PLink_LinkID, PLink_PhoneId, PLink_CreatedBy, PLink_CreatedDate, PLink_UpdatedDate, PLink_TimeStamp, 
     PLink_EntityID, PLink_RecordID, PLink_Type 
    ) 

    VALUES 
    (
     @c_PLink_LinkID, @c_PLink_PhoneId, @c_PLink_CreatedBy, @c_PLink_CreatedDate, @c_PLink_UpdatedDate, @c_PLink_TimeStamp, 
     @c_PLink_EntityID, @c_PLink_RecordID, @c_PLink_Type 
    ) 


    FETCH NEXT FROM @getPLID 
    INTO @Old_Phone_ID, @c_PLink_CreatedBy, @c_PLink_CreatedDate, @c_PLink_UpdatedDate, 
     @c_PLink_TimeStamp, @c_PLink_EntityID, @c_PLink_RecordID, @c_PLink_Type 
END 

注、私はフェッチリストに@Old_Phone_IDを返された - あなたはidでコピーされた携帯電話を見つけることができます。そして、最後のinsert-select-phoneはこの場合必要なくなりました(実際には、挿入されたすべての行に対してスカラー@PhoneIDを挿入しているため、多くの電話機の場合は正しくありません)。

+0

イワン、私はあなたの努力のために非常に感謝します!しかし、古い値の値をとるように@Old_PhoneIDを宣言するにはどうすればいいですか? –

+0

カーソルのselect文の 'PLink_PhoneId'です。 –

+0

'INSERT INTO Phone'部分、' WHERE PhoneID = @ Old_Phone_ID'は 'どこPhon_PhoneID = @ Old_Phone_ID'を意味しましたか? そして、私は@Old_Phone_IDを正しく宣言せずに置くことはできません。 –

関連する問題