【发布时间】:2013-08-28 21:51:57
【问题描述】:
我正在尝试创建一个存储过程 (MS SQL Server 2012),它复制许多行,然后将它们插入到同一个表中,并关联到另一个外部表。在复制的行上,我们还更改了 updateddate 和 createddate,以及创建和更新这些新插入行的用户。
这一切都很好,直到我们来到主键。该数据库是 Sage CRM 的数据库——它使用存储过程 (eware_get_identity_id) 来获取我们要插入的表的下一个主键 ID。这个 eware_get_identity_id 存储过程对其他表进行各种插入、更新和删除,所以我们不能使用函数来代替。我们无法更改数据库的组成,因此将列的类型更改为标识规范也不是一种选择。
我想做的(我知道我做不到)如下所示:
ALTER PROCEDURE Lead_CopySecuritiesToOpp
@lead_leadID int,
@oppo_opportunityID int,
@user_userID int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
INSERT INTO Security
(<columns hidden for clarity>,secu_CreatedDate,secu_UpdatedDate,secu_CreatedBy,secu_UpdatedBy,
secu_LeadId, secu_CaseId,secu_SecurityID)
SELECT <columns hidden for clarity>, GETDATE() as secu_CreatedDate, GETDATE() as secu_UpdatedDate, @user_userID as secu_CreatedBy,
@user_userID as secu_UpdatedBy, NULL as secu_LeadId, @oppo_opportunityID as secu_CaseId,
(exec [dbo].[eware_get_identity_id] 'Security') as secu_SecurityID
FROM Security
WHERE (secu_LeadId = @lead_leadID)
END
GO
显然我无法以这种方式内联执行存储过程((exec [dbo].[eware_get_identity_id] 'Security') as secu_SecurityID)。如果 Sage SP 没有更改数据,那么函数将是理想的,但它确实更改了数据,因此这不是一个选项。任何人都可以提出更好的方法吗?我确实考虑过在插入之前使用游标或临时表来获取数据?请提出建议。
【问题讨论】:
-
您是否考虑过使其具有事务性?假设您只是调用执行插入/更新等操作的 sproc,您应该能够将整个操作包装在事务中,并在出现任何问题时回滚。然后,您可以安全地调用身份生成函数并作为两个单独的语句插入,而不会出现不一致的数据库,如果出现问题
-
如果您无法更改数据库的组成,那么您如何创建/更改此
Lead_CopySecuritiesToOpp存储过程?是否有一些东西您可以更改/添加到数据库中? -
嗯,你看过一个叫
eware_get_identity_id_range的东西吗?看起来它是为了解决这个问题而写的。见这里:community.sagecrm.com/user_community/f/84/p/3205/…,提到它的帖子大约在一半... -
@RBarryYoung,Lead_CopySecuritiesToOpp 是我自己的 SP,我可以创建新的 SP,但不能更改现有的系统 SP 或表。我将看看那个 SQL 看看它是否可以提供帮助。塔
标签: sql-server stored-procedures