我总是使用类似下面的东西来实现它:
INSERT INTO TheTable
SELECT
@primaryKey,
@value1,
@value2
WHERE
NOT EXISTS
(SELECT
NULL
FROM
TheTable
WHERE
PrimaryKey = @primaryKey)
Run Code Online (Sandbox Code Playgroud)
...但是一旦加载,就会发生主键违规.这是唯一插入此表的语句.那么这是否意味着上述陈述不是原子的?
问题是,这几乎不可能随意重建.
也许我可以将其更改为以下内容:
INSERT INTO TheTable
WITH
(HOLDLOCK,
UPDLOCK,
ROWLOCK)
SELECT
@primaryKey,
@value1,
@value2
WHERE
NOT EXISTS
(SELECT
NULL
FROM
TheTable
WITH
(HOLDLOCK,
UPDLOCK,
ROWLOCK)
WHERE
PrimaryKey = @primaryKey)
Run Code Online (Sandbox Code Playgroud)
虽然,也许我使用错误的锁或使用过多的锁定或其他东西.
我在stackoverflow.com上看到了其他问题,其中答案是建议"IF(SELECT COUNT(*)... INSERT"等),但我总是在(可能是不正确的)假设单个SQL语句是原子的.
有没有人有任何想法?
使用SQL Server 2012.我想在表中插入唯一的字符串.我总是希望返回唯一字符串的行ID.现在,这可以通过两种方式实现.
哪种解决方案最好?
这是有问题的表:
CREATE TABLE [dbo].[Comment](
[CommentID] [int] IDENTITY(1,1) NOT NULL,
[Comment] [nvarchar](256) NOT NULL
CONSTRAINT [PK_Comment] PRIMARY KEY CLUSTERED([CommentID] ASC)
)
CREATE UNIQUE NONCLUSTERED INDEX [IX_Comment_Comment] ON [dbo].[Comment]
(
[Comment] ASC
)
Run Code Online (Sandbox Code Playgroud)
解决方案1:
SELECT首先检查字符串是否存在.如果确实如此,请返回ID.否则,INSERT新行并返回新创建的ID.
CREATE PROCEDURE [dbo].[add_comment]
@Comment [nvarchar](256)
AS
BEGIN
SET NOCOUNT ON
DECLARE @CommentID [int]
DECLARE @TransactionCount [int]
BEGIN TRY
SET @TransactionCount = @@TRANCOUNT
IF @TransactionCount = 0
BEGIN TRANSACTION
SELECT @CommentID = [CommentID] FROM [dbo].[Comment] WHERE …Run Code Online (Sandbox Code Playgroud)