SQL - 如何在根据另一个表检查条件时插入值?如果null生成新ID

时间:2016-04-19 02:02:14

标签: sql sql-server

我被赋予了一个使用游标来复制表的任务。 (不要问我为什么或建议我用其他方式导致给出任务要求的一部分)

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),
    @PersPhoneLinkID NVARCHAR(30),
    @PersPhoneID NVARCHAR(30)
        EXEC @companyId = crm_next_id 5
        EXEC @PersonId = crm_next_id 13
        EXEC @AddressId = crm_next_id 1



    -- 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, '1',
            GETDATE(), '1', GETDATE(), GETDATE(), Comp_SecTerr, Comp_WebSite

    FROM Company
    WHERE Comp_CompanyId = @comp_companyid
    AND Comp_Deleted is null



   ---- PersonLink Cursor ----------------------------------------------
    -- Declare Variables
    DECLARE @c_PeLi_PersonLinkId NVARCHAR(30)
    DECLARE @c_PeLi_PersonId NVARCHAR(30)
    DECLARE @c_PeLi_CompanyID NVARCHAR(30)
    DECLARE @c_PeLi_CreatedBy NVARCHAR(30)
    DECLARE @c_PeLi_CreatedDate NVARCHAR(30)
    DECLARE @c_PeLi_UpdatedBy NVARCHAR(30)
    DECLARE @c_PeLi_UpdatedDate NVARCHAR(30)
    DECLARE @c_PeLi_TimeStamp NVARCHAR(30)


    --Declare Cursor
    DECLARE PersonLinkCursor CURSOR FOR
    SELECT PeLi_PersonLinkId, PeLi_PersonId, PeLi_CompanyID, PeLi_CreatedBy, PeLi_CreatedDate, PeLi_UpdatedBy,
        PeLi_UpdatedDate, PeLi_TimeStamp
    FROM Person_Link
    INNER JOIN Person
    ON PeLi_PersonId = Pers_PersonId
    AND PeLi_CompanyID = @comp_companyid
    AND Pers_Deleted is null
    AND PeLi_Deleted is null

    --Open Cursor & fetch 1st row into variables
    OPEN PersonLinkCursor
    FETCH NEXT FROM PersonLinkCursor INTO @c_PeLi_PersonLinkId, @c_PeLi_PersonId, @c_PeLi_CompanyID, @c_PeLi_CreatedBy,
                                  @c_PeLi_CreatedDate, @c_PeLi_UpdatedBy, @c_PeLi_UpdatedDate, @c_PeLi_TimeStamp


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

        EXEC @c_PeLi_PersonLinkId = crm_next_id 31
        EXEC @PersonId = crm_next_id 13


    INSERT INTO Person_Link
    (
        PeLi_PersonLinkId, PeLi_PersonId, PeLi_CompanyID, PeLi_CreatedBy, PeLi_CreatedDate, PeLi_UpdatedBy,
        PeLi_UpdatedDate, PeLi_TimeStamp
    )
    VALUES
    (
        @c_PeLi_PersonLinkId, @PersonId, @companyId, '1', GETDATE(), '1', GETDATE(), GETDATE()
    )


    --Get next available row into variables
    FETCH NEXT FROM PersonLinkCursor INTO @c_PeLi_PersonLinkId, @c_PeLi_PersonId, @c_PeLi_CompanyID, @c_PeLi_CreatedBy,
                                  @c_PeLi_CreatedDate, @c_PeLi_UpdatedBy, @c_PeLi_UpdatedDate, @c_PeLi_TimeStamp

    END

    CLOSE PersonLinkCursor
    DEALLOCATE PersonLinkCursor



   ---- Person Cursor ----------------------------------------------
    -- Declare Variables
    DECLARE @c_Pers_PersonId NVARCHAR(30)
    DECLARE @c_Pers_CompanyId NVARCHAR(30)
    DECLARE @c_Pers_PrimaryUserId NVARCHAR(30)
    DECLARE @c_Pers_FirstName NVARCHAR(30)
    DECLARE @c_Pers_SecTerr NVARCHAR(30)
    DECLARE @c_Pers_CreatedBy NVARCHAR(30)
    DECLARE @c_Pers_CreatedDate NVARCHAR(30)
    DECLARE @c_Pers_UpdatedBy NVARCHAR(30)
    DECLARE @c_Pers_UpdatedDate NVARCHAR(30)
    DECLARE @c_Pers_TimeStamp NVARCHAR(30)


    --Declare Cursor
    DECLARE PersonCursor CURSOR FOR
    SELECT Pers_PersonId, Pers_CompanyId, Pers_PrimaryUserId, Pers_FirstName, Pers_SecTerr, Pers_CreatedBy,
           Pers_CreatedDate, Pers_UpdatedBy, Pers_UpdatedDate, Pers_TimeStamp
    FROM Person
    INNER JOIN Person_Link
    ON Pers_PersonId = PeLi_PersonId
    AND PeLi_CompanyID = @comp_companyid
    AND Pers_Deleted is null
    AND PeLi_Deleted is null


    --Open Cursor & fetch 1st row into variables
    OPEN PersonCursor
    FETCH NEXT FROM PersonCursor INTO @c_Pers_PersonId, @c_Pers_CompanyId, @c_Pers_PrimaryUserId, @c_Pers_FirstName,
                                  @c_Pers_SecTerr, @c_Pers_CreatedBy, @c_Pers_CreatedDate, @c_Pers_UpdatedBy,
                                  @c_Pers_UpdatedDate, @c_Pers_TimeStamp


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

    EXEC @PersonId = crm_next_id 13


    INSERT INTO Person
    (
        Pers_PersonId, Pers_CompanyId, Pers_PrimaryUserId, Pers_FirstName, Pers_SecTerr, Pers_CreatedBy,
        Pers_CreatedDate, Pers_UpdatedBy, Pers_UpdatedDate, Pers_TimeStamp
    )
    VALUES
    (
        @PersonId, @companyId, @c_Pers_PrimaryUserId, @c_Pers_FirstName, @c_Pers_SecTerr, '1',
        GETDATE(), '1', GETDATE(), GETDATE()
    )


    --Get next available row into variables
    FETCH NEXT FROM PersonCursor INTO @c_Pers_PersonId, @c_Pers_CompanyId, @c_Pers_PrimaryUserId, @c_Pers_FirstName,
                                  @c_Pers_SecTerr, @c_Pers_CreatedBy, @c_Pers_CreatedDate, @c_Pers_UpdatedBy,
                                  @c_Pers_UpdatedDate, @c_Pers_TimeStamp

    END

    CLOSE PersonCursor
    DEALLOCATE PersonCursor

END

这是我的表结构:

公司表:

comp_companyid | comp_primarypersonid | comp_primaryaddressid | comp_name
-------------------------------------------------------------------------
2              | 2                    | 2                     | company 2
3              | 3                    | 3                     | company 3

人员表:

pers_personid  | pers_companyid       | pers_primaryaddressid | pers_name
-------------------------------------------------------------------------
2              | 2                    | 2                     | person 2
3              | 3                    | 3                     | person 3
4              | 2                    | 2                     | person 4

人员链接表:

peli_personlinkid |    peli_personid     | peli_companyid
-------------------------------------------------------------------------
2                 | 2                    | 2                  
3                 | 3                    | 3                               
4                 | 4                    | 2

现在我将值插入光标循环中的每个表中,如上所示。我想从PeLi_PersonID&中插入PersonLink的值。来自Pers_PersonID的{​​{1}}来自Person的{​​{1}} Comp_PrimaryPersonId,如果ID存在,请使用ID,否则生成下一个ID。我怎么做?谢谢!

我试过这个:

Company

它成功地从公司INSERT INTO Person_Link ( PeLi_PersonLinkId, PeLi_PersonId, PeLi_CompanyID, PeLi_CreatedBy, PeLi_CreatedDate, PeLi_UpdatedBy, PeLi_UpdatedDate, PeLi_TimeStamp ) VALUES ( @c_PeLi_PersonLinkId,(SELECT @PersonID FROM Company WHERE Comp_PrimaryPersonId is not null AND Comp_CompanyId = @Comp_CompanyId), @companyId, '1', GETDATE(), '1', GETDATE(), GETDATE() ) 获取了人员ID的值,但重复的Comp_PrimaryPersonID将不会生成新的ID。我该如何进行适当的状况检查?我想在循环中进行条件检查,定义:如果PeLi_PersonId的值存在,请使用值,如果没有得到下一个id。谢谢!

1 个答案:

答案 0 :(得分:0)

与之前的步骤相同的情况 - 将它们放入单个游标中。首先 - 复制Person并获得新的personid,第二个 - 插入Person_Link,链接到新创建的人。

如果您需要创建另一个Person_Link(这很奇怪,因为您刚刚将所有的Person_Links复制到某个“主要”人员 - 您需要新的Person_Id。

(SELECT @PersonID FROM Company 
WHERE Comp_PrimaryPersonId is not null AND Comp_CompanyId = @Comp_CompanyId)

在此选择中,您可以引用旧的@Comp_CompanyId,这样您就可以获得旧的Person_Id,而您只需要一个新的Person_Id(可以在@companyId id下找到)。

但是你不会用这个选择获得甚至是旧的id - 因为它选择了@PersonID变量的常量值,该变量在此选择之前甚至没有被初始化,因此包含来自先前使用地点的一些垃圾。

无论如何,由于第一次插入Company,你已经失去与新公司的主要人的关系 - 它新生成的Comp_PrimaryPersonId值链接到任何内容。

解决问题的一种方法是检查游标内部@c_PeLi_PersonId是否与旧公司 Comp_PrimaryPersonId相同并更新新公司 Comp_PrimaryPersonId字段。将旧公司的Comp_PrimaryPersonId存储到脚本开头的变量中,并在游标中使用它。