SQL Server:在存储过程中插入游标 [英] SQL Server : Insert cursor within stored procedure

查看:355
本文介绍了SQL Server:在存储过程中插入游标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的SQL Server,并给了一个任务,我必须使用光标重复记录电话链接表。其他表我设法重复,而不需要使用游标。但是我有电话链接表的主键约束问题。有人会帮助我吗?谢谢。以下是我的存储过程。进入参数是comp_companyid。我的要求是将每个列复制到同一个表中,并生成新的主键&外部键。



P / S:




  • EntityID = 5

  • EntityID = 13(人)



个人电话链接,以及添加。但我只需要解决这个问题,然后我可以参考这个当我在做手机。



另外,一个公司可以有多个人,地址。 p>

  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 b $ b @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

- 添加公司
INSERT INTO公司

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
公司
WHERE
Comp_CompanyId = @comp_companyid
$ b b - 添加Person_Link无类型
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

- 添加人
INSERT INTO人

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

- 添加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


- 添加地址
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地址
INNER JOIN Address_Link
ON Addr_AddressId = AdLi_AddressId
和AdLi_CompanyID = @comp_companyid



- 添加PhoneLink
- 声明变量


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

$ b b --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
和PLink_RecordID = @Comp_CompanyId

- 打开光标&获取第一行到变量
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

- 检查新行
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



- 获取下一行变量
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



- 添加公司电话
INSERT INTO电话

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电话
INNER JOIN PhoneLink
ON Phon_PhoneId = PLink_PhoneId
和PLink_EntityID = 5
和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
b @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
pre>

如果需要生成PhoneID,您还必须将它放在光标内。
同样从游标的选择中删除PLink_LinkID和PLink_PhoneId,因为你不需要原始值。并且,当然,从抓取列表中删除。如上所示。



但是,

如果我的假设是正确的,那么你会有点错误的方式。如果 PhoneLink 表是将某些电话链接到新创建的实体/公司的表,则需要先复制电话(并为该记录生成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电话

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_Link ID,@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 $ b注意,我将 @Old_Phone_ID 返回到获取列表中 - $ b


$ b <所以你可以通过id找到复制的手机。最后插入选择手机不再需要在这种情况下(实际上在许多手机的情况下是不正确的,因为它插入标量@PhoneID,所有插入的行相同)。


I'm new to SQL Server and was given a task where I have to use cursor to duplicate records for Phone Link table. Other tables I have managed to duplicate without needing to use cursor. However I have primary key constraint problem with Phone Link table. Will someone please assist me? Thank you. Following is my stored procedure. Intake parameter is comp_companyid. My requirement is to duplicate every column into the same table and generate new primary key & foreign key.

P/S:

  • EntityID = 5 (Company)
  • EntityID = 13 (Person)

As I have person phone & person phone link to add on afterwards as well. But I just need to solve this first then I can refer to this when I'm doing person phone.

Also, one company can have multiple person, address.

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

Appreciate if you can tell me which part I've done wrong. Thank you for your time and effort in advance!

解决方案

Not sure what all of inserted columns mean but if you are inserting many rows you need to generate another unique id for each row. So you have to move ID generation code into cursor body instead of placing it before cursor declaration and call this generator each iteration.

...
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

If PhoneID needs to be generated too - you have to place it inside your cursor too. Also remove PLink_LinkID and PLink_PhoneId from cursors's select since you don't need original values. And, of course, remove'em from fetch lists. Just as shown above.

But,
if my assumptions are correct then you are going a bit wrong way. If PhoneLink table is a table that links some Phones to newly created Entity/Company, then you need to copy Phone first (and generate ID for that record) and after that - to build a link between new Phone_ID and new Company_ID. Now, if you always have only one Phone per Company (which would be a bit strange) then you don't need cursor. But if you can have several phones per company then you need to generate several new Phone_IDs. Which means, you need to iterate through phones and links instead of iterating links only. And the code should look like:

...
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

Note, I returned @Old_Phone_ID into fetch list - so you could locate copied phone by id. And last insert-select-phone is no longer needed in this case (and actually is incorrect in many phones case 'cause it's inserting scalar @PhoneID, same for all inserted rows).

这篇关于SQL Server:在存储过程中插入游标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆