相关疑难解决方法(0)

只有在它不存在的情况下才插入一行

我总是使用类似下面的东西来实现它:

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 t-sql sql-server concurrency locking

68
推荐指数
3
解决办法
3万
查看次数

使用SELECT重复检查还是依赖唯一索引?

使用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)

sql sql-server

1
推荐指数
1
解决办法
171
查看次数

标签 统计

sql ×2

sql-server ×2

concurrency ×1

locking ×1

t-sql ×1