Phi*_*enn 49 sql t-sql sql-server sql-server-2005
How do you say以下Microsoft SQL Server 2005:
IF EXISTS (SELECT * FROM Table WHERE FieldValue='') THEN
SELECT TableID FROM Table WHERE FieldValue=''
ELSE
INSERT INTO TABLE(FieldValue) VALUES('')
SELECT TableID FROM Table WHERE TableID=SCOPE_IDENTITY()
END IF
Run Code Online (Sandbox Code Playgroud)
我要做的是查看是否已经有一个空白的fieldvalue,如果有则返回TableID,否则插入一个空白的fieldvalue并返回相应的主键.
zvo*_*kov 60
您需要在事务中执行此操作以确保两个并发客户端不会两次插入相同的fieldValue:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
DECLARE @id AS INT
SELECT @id = tableId FROM table WHERE fieldValue=@newValue
IF @id IS NULL
BEGIN
INSERT INTO table (fieldValue) VALUES (@newValue)
SELECT @id = SCOPE_IDENTITY()
END
SELECT @id
COMMIT TRANSACTION
Run Code Online (Sandbox Code Playgroud)
您还可以使用双重检查锁定来减少锁定开销
DECLARE @id AS INT
SELECT @id = tableID FROM table (NOLOCK) WHERE fieldValue=@newValue
IF @id IS NULL
BEGIN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT @id = tableID FROM table WHERE fieldValue=@newValue
IF @id IS NULL
BEGIN
INSERT INTO table (fieldValue) VALUES (@newValue)
SELECT @id = SCOPE_IDENTITY()
END
COMMIT TRANSACTION
END
SELECT @id
Run Code Online (Sandbox Code Playgroud)
至于为什么需要ISOLATION LEVEL SERIALIZABLE,当你在一个可序列化的事务中时,第一个命中表的SELECT会创建一个覆盖记录所在位置的范围锁,因此在此事务结束之前没有其他人可以插入相同的记录.
如果没有ISOLATION LEVEL SERIALIZABLE,默认隔离级别(READ COMMITTED)将不会在读取时锁定表,因此在SELECT和UPDATE之间,某人仍然可以插入.具有READ COMMITTED隔离级别的事务不会导致SELECT锁定.使用REPEATABLE READS的事务会锁定记录(如果找到)而不是间隙.
Jan*_*ane 32
IF EXISTS (SELECT 1 FROM Table WHERE FieldValue='')
BEGIN
SELECT TableID FROM Table WHERE FieldValue=''
END
ELSE
BEGIN
INSERT INTO TABLE(FieldValue) VALUES('')
SELECT SCOPE_IDENTITY() AS TableID
END
Run Code Online (Sandbox Code Playgroud)
有关IF ELSE的更多信息,请参见此处
注意:编写没有SQL Server安装方便双重检查,但我认为这是正确的
另外,我已经将EXISTS位更改为SELECT 1而不是SELECT*,因为您不关心EXISTS中返回的内容,只要有什么东西我也改变了SCOPE_IDENTITY()位以返回标识假设TableID是标识列
你很亲密:
IF EXISTS (SELECT * FROM Table WHERE FieldValue='')
SELECT TableID FROM Table WHERE FieldValue=''
ELSE
BEGIN
INSERT INTO TABLE (FieldValue) VALUES ('')
SELECT TableID FROM Table WHERE TableID=SCOPE_IDENTITY()
END
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
404410 次 |
| 最近记录: |