Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
T-SQL更新或插入最佳方法_Sql_Sql Server_Sql Server 2005_Tsql - Fatal编程技术网

T-SQL更新或插入最佳方法

T-SQL更新或插入最佳方法,sql,sql-server,sql-server-2005,tsql,Sql,Sql Server,Sql Server 2005,Tsql,可能重复: 如果新记录不存在,我将使用以下构造插入新记录。如果它存在,那么它将更新该记录。我想知道它是否是线程安全的。我的意思是两个线程尝试插入记录,这将创建重复的条目。处理此类查询的最佳方法是什么?我是否需要将这些语句放入事务块中 UPDATE Table1 SET (...) WHERE Column1='SomeValue' IF @@ROWCOUNT=0 INSERT INTO Table1 VALUES (...) 如果您先插入,则会更安全一些: insert Table

可能重复:

如果新记录不存在,我将使用以下构造插入新记录。如果它存在,那么它将更新该记录。我想知道它是否是线程安全的。我的意思是两个线程尝试插入记录,这将创建重复的条目。处理此类查询的最佳方法是什么?我是否需要将这些语句放入事务块中

UPDATE Table1 SET (...) WHERE Column1='SomeValue'

IF @@ROWCOUNT=0
    INSERT INTO Table1 VALUES (...)

如果您先插入,则会更安全一些:

insert Table1 (...columns...) select ..values... where not exists (
    select * from table1 where Column1 = 'SomeValue')

if @@rowcount = 0 update Table1 set (...) where Column1 = 'SomeValue'

这样,existance检查和insert是同一语句的一部分。因此,在
更新
插入
之间没有空间,其他连接可以在其中插入行。

如果先执行插入操作,则会更安全一些:

insert Table1 (...columns...) select ..values... where not exists (
    select * from table1 where Column1 = 'SomeValue')

if @@rowcount = 0 update Table1 set (...) where Column1 = 'SomeValue'

这样,existance检查和insert是同一语句的一部分。因此,在
更新
插入
之间没有空间,其他连接可以插入行。

这是对Andomar文章的更详细解释。我把这归功于Andomar,只是说明了如何更详细地修改一个小错误

DECLARE @s VARCHAR(100)
SET @s = 'somevalue' 

DECLARE @t TABLE (column1 VARCHAR(100), column2 VARCHAR(18))

INSERT @t 
SELECT @s, 'First example'
WHERE NOT EXISTS ( SELECT 1 FROM @t WHERE Column1 = @s) 
IF @@rowcount = 0 UPDATE @t SET column2 = 'Second example' WHERE Column1 = @s

-- at first the value does not exists and is inserted
SELECT * FROM @t

-- same script again, notice how the second example is chosen because it already exists
INSERT @t 
SELECT @s, 'First example'
WHERE NOT EXISTS ( SELECT 1 FROM @t WHERE Column1 = @s) 
IF @@rowcount = 0 UPDATE @t SET column2 = 'Second example' WHERE Column1 = @s

-- new the line exists and column 2 is updated
SELECT * FROM @t

column1     column2
----------- -------------
somevalue   First example

column1     column2
----------- --------------
somevalue   Second example

这是对安多马尔文章的更详细的解释。我把这归功于Andomar,只是说明了如何更详细地修改一个小错误

DECLARE @s VARCHAR(100)
SET @s = 'somevalue' 

DECLARE @t TABLE (column1 VARCHAR(100), column2 VARCHAR(18))

INSERT @t 
SELECT @s, 'First example'
WHERE NOT EXISTS ( SELECT 1 FROM @t WHERE Column1 = @s) 
IF @@rowcount = 0 UPDATE @t SET column2 = 'Second example' WHERE Column1 = @s

-- at first the value does not exists and is inserted
SELECT * FROM @t

-- same script again, notice how the second example is chosen because it already exists
INSERT @t 
SELECT @s, 'First example'
WHERE NOT EXISTS ( SELECT 1 FROM @t WHERE Column1 = @s) 
IF @@rowcount = 0 UPDATE @t SET column2 = 'Second example' WHERE Column1 = @s

-- new the line exists and column 2 is updated
SELECT * FROM @t

column1     column2
----------- -------------
somevalue   First example

column1     column2
----------- --------------
somevalue   Second example

Insert语句的语法不正确。SQL Server不喜欢它。我想我可以使用序列化锁。@Andomar:
其中
基本上不是
插入
的一部分,因此它不能与
插入…值一起使用。但是它可以是
SELECT
的一部分,这意味着您可以将
WHERE
INSERT一起使用…SELECT
@kumar,Andriy M:您是对的,编辑的INSERT语句语法不正确。SQL Server不喜欢它。我想我可以使用序列化锁。@Andomar:
其中
基本上不是
插入
的一部分,因此它不能与
插入…值一起使用。但是它可以是
SELECT
的一部分,这意味着您可以将
WHERE
插入一起使用…SELECT
@kumar,Andriy M:您是对的,在答案中进行了编辑