gpt4 book ai didi

sql-server - 如何使用最少的操作在 SQL Server 2012 中使用 "INSERT or SELECT"?

转载 作者:行者123 更新时间:2023-12-01 11:32:22 27 4
gpt4 key购买 nike

我一直在寻找与此类似的问题,但我还没有找到任何东西,所以如果之前有人问过这个问题,这至少可以为那些无知的人提供一个很好的指导正确的命名法。

如果某行尚不存在,我想根据唯一键INSERT INTO 一个表。它确实存在,那么我想获取该行的主键Id。

想象一个包含电子邮件地址的表:

EmailAddressId(PK) | EmailAddress(UK)

我想INSERT 到那个表中一个新的电子邮件地址,但是EmailAddress 有一个唯一的约束。因此,如果新电子邮件地址与现有电子邮件地址相同,INSERT 将失败。在这种情况下,我想从数据库中为 EmailAddress 选择现有的 EmailAddressId

我希望以最少的操作次数来执行此操作,假设碰撞很少见。

因此,我在存储过程中设置了一个 TRY...CATCH block ,如下所示:

ALTER PROCEDURE [dbo].[EmailAddressWrite]
@EmailAddress nvarchar[256]
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION

DECLARE @EmailAddressId INT

BEGIN TRY
INSERT INTO EmailAddress VALUES (@EmailAddress)
SET @EmailAddressId = (SELECT SCOPE_IDENTITY())
END TRY
BEGIN CATCH
SET @EmailAddressId = (SELECT EmailAddressId FROM EmailAddress WHERE EmailAddress = @EmailAddress)
END CATCH

--Do some more stuff with the Id now.

COMMIT TRANSACTION

RETURN @EmailAddressId
END

上面的代码运行并产生了所需的结果,但是互联网让我认为以这种方式使用 TRY...CATCH 可能会很慢...因此我不确定这是否是最优解。

我只找到了另一种解决方案,即先SELECT,再INSERT。这将导致几乎所有时间都进行 2 次操作,因为我预计重复的电子邮件地址很少(至少一个月或更长时间)。

  1. 这是实现对 INSERT 的 1 次操作和对 ​​INSERT 的 2 次操作失败的最佳解决方案吗?
  2. 还有哪些其他解决方案可以实现对 INSERT 的 1 操作和 2INSERT 操作失败?

如果我误用了任何术语,请更正。

最佳答案

DECLARE @id INT

DECLARE @newid TABLE
(
emailAddressId INT NOT NULL PRIMARY KEY
)

;
WITH t AS
(
SELECT *
FROM emailAddress WITH (ROWLOCK, HOLDLOCK)
WHERE emailAddress = @emailAddress
)
MERGE
INTO t
USING (
SELECT @emailAddress
) s (emailAddress)
ON 1 = 1
WHEN NOT MATCHED BY TARGET THEN
INSERT (emailAddress)
VALUES (emailAddress)
WHEN MATCHED THEN
UPDATE
SET @id = 1
OUTPUT INSERTED.emailAddressId
INTO @newid
;

关于sql-server - 如何使用最少的操作在 SQL Server 2012 中使用 "INSERT or SELECT"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31126488/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com