[英]SQL Server : Insert cursor within stored procedure
我是SQL Server的新手,并且被赋予一项任务,在该任务中,我必须使用光标来复制Phone Link表的记录。 我设法复制了其他表格,而无需使用游标。 但是我有电话链接表的主键约束问题。 有人可以帮我吗? 谢谢。 以下是我的存储过程。 摄入参数是comp_companyid。 我的要求是将每一列复制到同一张表中,并生成新的主键和外键。
P / S:
由于我还有个人电话和个人电话链接也可以添加。 但是我只需要先解决这个问题,然后在做人电话时就可以参考。
同样,一个公司可以有多个人,地址。
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.