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
我是否可以使用一条SQL语句更新多个记录,其中更新值取决于要更新的记录?_Sql_Sql Update_Records - Fatal编程技术网

我是否可以使用一条SQL语句更新多个记录,其中更新值取决于要更新的记录?

我是否可以使用一条SQL语句更新多个记录,其中更新值取决于要更新的记录?,sql,sql-update,records,Sql,Sql Update,Records,假设有两个表: STATES保存可用状态的列表-key field=STATE\u ID。另一个键是DOMAIN\u ID,STATE\u NAME。因此,存在状态名称相同但域ID不同的记录。 对象包含所有对象的列表,每个对象都有自己的状态键field=OBJECT\u ID。还包含一个字段state\u ID。 假设我有一个大约1000个对象的列表,它们需要更新到各自域中关闭的状态 对于单个对象,比如object_ID 12345,我可以使用SQL语句: update OBJECTS set

假设有两个表:

STATES保存可用状态的列表-key field=STATE\u ID。另一个键是DOMAIN\u ID,STATE\u NAME。因此,存在状态名称相同但域ID不同的记录。 对象包含所有对象的列表,每个对象都有自己的状态键field=OBJECT\u ID。还包含一个字段state\u ID。 假设我有一个大约1000个对象的列表,它们需要更新到各自域中关闭的状态

对于单个对象,比如object_ID 12345,我可以使用SQL语句:

update OBJECTS
set STATE_ID =
(
  select STATE_ID from STATES
  where STATE_NAME= 'CLOSED'
  and DOMAIN_ID =
  (
    select DOMAIN_ID from STATES a, OBJECTS b
    where a.STATE_ID = b.STATE_ID and b.OBJECT_ID = 12345)
  )
) where OBJECT_ID = 12345
是否可以使用一条语句更新多个对象?问题的症结似乎在于我无法回避在SQL语句中的两个位置定义OBJECT_ID

出于显而易见的原因,以下声明不起作用:

update OBJECTS
set STATE_ID =
(
  select STATE_ID from STATES
  where STATE_NAME= 'CLOSED'
  and DOMAIN_ID =
  (
    select DOMAIN_ID from STATES a, OBJECTS b
    where a.STATE_ID = b.STATE_ID and b.OBJECT_ID in
    (
      select distinct OBJECT_ID from OBJECTS_TO_UPDATE
    )
  )
) where OBJECT_ID in (select distinct OBJECT_ID from OBJECTS_TO_UPDATE)
有谁能给我一个提示,我能做些什么来解决这个问题


谢谢。

您可以使用表名对象,因为它在范围内,例如

UPDATE OBJECTS
  SET STATE_ID = (
                  SELECT STATE_ID 
                    FROM STATES
                   WHERE STATE_NAME = 'CLOSED'
                         AND DOMAIN_ID = (
                                          SELECT DOMAIN_ID 
                                            FROM STATES a, 
                                                 OBJECTS b
                                           WHERE a.STATE_ID = b.STATE_ID 
                                                 AND b.OBJECT_ID = OBJECTS.OBJECT_ID
                                         )
                 )
 WHERE EXISTS (
               SELECT * 
                 FROM STATES
                WHERE STATE_NAME = 'CLOSED'
                      AND DOMAIN_ID = (
                                       SELECT DOMAIN_ID 
                                         FROM STATES a, 
                                              OBJECTS b
                                        WHERE a.STATE_ID = b.STATE_ID 
                                              AND b.OBJECT_ID = OBJECTS.OBJECT_ID
                                      )
                 );
SQL Server、MS Access、MySQL?解决方案:

我想这就是关键。您可能希望先用SELECT*替换UPDATE和SET子句,并检查结果集是否正确:

update o
set STATE_ID = s_closed.STATE_ID
from
   Objects o
      inner join
   States s_current
      on
         o.STATE_ID = s.STATE_ID
      inner join
   States s_closed
      on
         s_current.DOMAIN_ID = s_closed.DOMAIN_ID and
         s_closed.STATE_NAME = 'Closed'
      inner join
   OBJECTS_TO_UPDATE otu
      on
         otu.OBJECT_ID= o.OBJECT_ID

如果不进一步了解表的结构,我无法确定您需要什么样的SQL。但是,获取新状态ID的子查询可以像某天所说的那样引用您正在更新的表

例如

update
  OBJECTS
set
  STATE_ID =
    (
      select
        NEW_STATE.STATE_ID
      from
        STATES    AS OLD_STATE
      inner join
        STATES    AS NEW_STATE
          ON NEW_STATE.DOMAIN_ID = OLD_STATE.DOMAIN_ID
      where
        OLD_STATE.STATE_ID = OBJECTS.STATE_ID
        AND NEW_STATE.STATE_NAME = 'CLOSED'
    )
where
  OBJECT_ID in (select distinct OBJECT_ID from OBJECTS_TO_UPDATE)

通过这种方式,您可以确保子查询只为OBJECTS表中的任何给定记录返回一个STATE\u ID。

您已经在功能上更改了OP想要执行的操作。只有OBJECTS表的一个子集需要更新OBJECTS-TO-UPDATE中具有OBJECT-ID的表table@Dems:本应强调如何在范围内引用该表,但为了完整性和过度使用,我已更新了我的答案。嗯,WHERE子句不需要按照OPs吗?where OBJECT_ID in select distinct OBJECT_ID from OBJECTS_TO_UPDATE@Dems:我只是在看问题中的第一个查询教人钓鱼等等。有一天,谢谢你的建议,它已经测试过了。关于DEM的评论,我看到了最初的答案,计算出where子句需要更新,并在我的测试中对其进行了更改,因此没有造成任何伤害。我只是希望有人能为我指明正确的方向,而不是希望有人能给出我所需要的SQL。但是,感谢您更正您的答案,因为它将帮助其他读者。这应该适用于MS SQL Server,但不适用于Oracle。完全取决于OP使用的RDBMS,我猜…@Dems-没错,我会在顶部添加一个注释-但请注意,我们使用的是STATES表中的两行,我认为这与OP在第一个查询中的内容相匹配-因此您的答案也需要一些工作:-因为一些RDBMS允许某些语法,而其他RDBMS不允许,你在用什么?Oracle、MySQL等?