Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.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
SQL Server:更新列中不存在的值_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

SQL Server:更新列中不存在的值

SQL Server:更新列中不存在的值,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我正在使用SQLServer2008,并试图创建一条语句,如果满足某个参数,该语句将更新另一个表中一行中的单个值。我需要尽可能简单地让我的团队成员使用 所以在本例中,我想存储两个值,销售订单和引用。不幸的是,销售订单有一个唯一的标识符,我需要记录并输入到jobs表中,而不是实际的销售订单引用 需要满足的参数是,销售订单唯一标识符不能存在于jobs表的Sales order列中的任何位置。当while值设置为1时,我可以让它工作,但当它设置为0时,我的大脑中应该设置为0。有人知道为什么这样不行吗

我正在使用SQLServer2008,并试图创建一条语句,如果满足某个参数,该语句将更新另一个表中一行中的单个值。我需要尽可能简单地让我的团队成员使用

所以在本例中,我想存储两个值,销售订单和引用。不幸的是,销售订单有一个唯一的标识符,我需要记录并输入到jobs表中,而不是实际的销售订单引用

需要满足的参数是,销售订单唯一标识符不能存在于jobs表的Sales order列中的任何位置。当while值设置为1时,我可以让它工作,但当它设置为0时,我的大脑中应该设置为0。有人知道为什么这样不行吗

/****** Attach an SO to a WO  ******/

/****** ONLY EDIT THE VALUES BETWEEN '' ******/
Declare @Reference nvarchar(30);
Set @Reference = 'WO16119';

Declare @SO nvarchar(30);
Set @SO = '0000016205';

/****** DO NOT ALTER THE CODE BEYOND THIS POINT!!!!!!!!!!!!! ******/

/* store more values */
Declare @SOID nvarchar(30);
Set @SOID = (Select SOPOrderReturnID
        FROM Test_DB.dbo.SOTable
        Where DocumentNo = @SO);

/*  check if update should run */                           
Declare @Check nvarchar (30);
Set @Check = (Select case when exists   (select * 
                                from Test_DB.dbo.Jobs 
                                where SalesOrderNumber != @SOID)
                                then CAST(1 AS BIT)
                                ELSE CAST(0 AS BIT) End)
While (@Check = 0)

/* if check is true run code below */
Begin
Update Test_DB.dbo.jobs
SET SalesOrderNumber = (Select SOPOrderReturnID
                    FROM Test_DB.dbo.SOPOrderReturn
                    Where DocumentNo = @SO)
Where Reference = @Reference
END;

一些评论。首先,为了避免陷入永无止境的循环,您可能需要更改IF语句的while。您没有更改@check值,因此它将永远运行:

IF (@Check = 0)
BEGIN
   /* if check is true run code below */
   Update Test_DB.dbo.jobs
   SET SalesOrderNumber = (Select SOPOrderReturnID
                FROM Test_DB.dbo.SOPOrderReturn
                Where DocumentNo = @SO)
   Where Reference = @Reference
END
然后,在不了解您的应用程序的情况下,我会说,您进行检查的方式将要求您锁定表,以避免其他用户使您选择的结果无效

我将转而在您想要唯一的列上创建一个唯一约束,并优雅地处理错误。这样,您就不需要在表上创建大锁

CREATE UNIQUE INDEX IX_UniqueIndex ON Test_DB.dbo.Jobs(SalesOrderNumber)
根据您的评论,如果无法创建唯一索引,您可能希望尝试以下SQL,尽管它可能会导致太多锁定并受竞争条件的影响:

IF NOT EXISTS (SELECT 1 FROM Test_DB.dbo.Jobs j INNER JOIN Test_DB.dbo.SOTable so ON j.SalesOrderNumber = so.SPOrderReturnId)
BEGIN
    UPDATE Test_DB.dbo.jobs
    SET SalesOrderNumber =  so.SOPOrderReturnID
    FROM
        Test_DB.dbo.Jobs j 
        INNER JOIN Test_DB.dbo.SOTable so ON j.SalesOrderNumber = so.SPOrderReturnId
    Where 
        Reference = @Reference
END
这样做的风险在于,您运行的是单独的查询(选择和更新),因此它们之间的数据库状态可能会发生变化。因此,第一个查询可能不会返回该Id的任何内容,但在更新时,其他用户已插入/更新该数据,因此先前的结果不再为真

您可以尝试通过使用隔离级别来避免此问题,该隔离级别在读取时锁定表(如Serializable),但这可能会导致数据库中出现锁甚至死锁


这里最好的解决方案是唯一索引。如果表中的某一列必须是唯一的,那么通过定义约束,最好的控制系统就是数据库本身。

而且当我让它工作时,它会反复运行,我不相信它正在执行检查。为了澄清这一点,SalesOrderNumber列中不能存在值以运行此更新脚本。您有无限的循环
而(@Check=0)
使用
如果(@Check=0)
您的意思是
如果
,而不是
,因为
提供了信息,所以它只能运行一次。我现在遇到的问题是,它没有检查列中是否存在该值。是的,我想说这正是正确的处理方法,代码最少,并避免争用条件。因此,在这种情况下,我会只检查索引吗?如果检查设置为1,则它将在分钟运行,但这不是正确的方法,该列中不需要该值才能运行更新。无检查。您只需尝试更新,如果该值存在,索引将抱怨并抛出错误。您可以处理错误,也就是说。我现在可以在括号内输入SalesOrderNumber吗?从未使用过唯一的索引我不明白它是如何工作的,如果这些是愚蠢的问题,很抱歉。更新后会有更多的解释,但您应该在线查看一些关于数据库上的隔离级别、锁、死锁和竞争条件的文档。