繁体   English   中英

SQL Server:在存储过程中插入游标

[英]SQL Server : Insert cursor within stored procedure

我是SQL Server的新手,并且被赋予一项任务,在该任务中,我必须使用光标来复制Phone Link表的记录。 我设法复制了其他表格,而无需使用游标。 但是我有电话链接表的主键约束问题。 有人可以帮我吗? 谢谢。 以下是我的存储过程。 摄入参数是comp_companyid。 我的要求是将每一列复制到同一张表中,并生成新的主键和外键。

P / S:

  • EntityID = 5(公司)
  • EntityID = 13(人员)

由于我还有个人电话和个人电话链接也可以添加。 但是我只需要先解决这个问题,然后在做人电话时就可以参考。

同样,一个公司可以有多个人,地址。

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

如果您能告诉我我做错了哪一部分,请感谢。 谢谢您的时间和精力!

不确定所有插入的列的含义,但是如果要插入许多行,则需要为每行生成另一个唯一的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。 并且,当然,从获取列表中删除它们。 如上图所示。

但,
如果我的假设是正确的,那你就走错了路。 如果PhoneLink表是将某些电话链接到新创建的实体/公司的表,则您需要先复制Phone(并为该记录生成ID),然后再复制-在新Phone_ID和新Company_ID之间建立链接。 现在,如果每个公司始终只有一部电话(这有点奇怪),那么您就不需要游标了。 但是,如果每个公司可以拥有多个电话,则需要生成多个新的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查找复制的电话。 在这种情况下,不再需要最后一个插入选择电话(在许多电话情况下实际上是不正确的,因为它正在插入标量@PhoneID,所有插入的行都一样)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM