SQL Server:在存储过程中插入游标 [英] SQL Server : Insert cursor within stored procedure
问题描述
我是新来的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生成代码移动到游标体中,而不是将其放在游标声明之前,并在每次迭代中调用此生成器。
。 ..
pre>
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
如果需要生成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屋!