当前位置: 首页 > 面试题库 >

我在Oracle中加入联接的更新语句有什么问题?

家弘业
2023-03-14
问题内容

我正在使用 Oracle 10g数据库。

我有以下两个表:

T_DEBTOR :
    - ID_DEBTOR
    - HEADER
T_ELEMENT :
    - ID_ELEMENT
    - ID_DEBTOR
    - INSURER

使用ID_DEBTOR字段将这两个表连接在一起。

仅当HEADER不为null时,我才想使用关联的T_DEBTOR.HEADER更新T_ELEMENT.INSURER值。换句话说:

If T_DEBTOR.HEADER != null
    Then T_ELEMENT.INSURER = T_DEBTOR.HEADER
    Else T_ELEMENT.INSURER is not modified!

我尝试使用以下SQL查询:

update
    T_ELEMENT elt
    set elt.INSURER = (
        select HEADER
            from T_DEBTOR debtor
            where
                debtor.HEADER is not null
                and debtor.ID_DEBTOR = elt.ID_DEBTOR);

该查询适用于与HEADER不为null的债务人链接的所有元素。但是,当T_DEBTOR.HEADER为null时,此查询会将T_ELEMENT.INSURER设置为null,这是不正确的。

IE:

If T_DEBTOR.HEADER != null
    Then T_ELEMENT.INSURER = T_DEBTOR.HEADER   --> This part is OK
    Else T_ELEMENT.INSURER is set to null      --> This part is NOT OK

我的查询出了什么问题?

编辑,关于Brian Storrar的答案:

我想做的是这样的:

update
    T_ELEMENT elt
    set elt.INSURER = (
        select HEADER
            from T_DEBTOR debtor
            where
                debtor.HEADER is not null
                and debtor.ID_DEBTOR = elt.ID_DEBTOR)
    where debtor.HEADER is not null;

问题答案:

好问题。

为了模拟您的情况,我创建了示例表:

SQL> create table t_debtor(id_debtor,header)
  2  as
  3  select 1, 'Header 1' from dual union all
  4  select 2, null from dual union all
  5  select 3, 'Header 3' from dual
  6  /

Tabel is aangemaakt.

SQL> create table t_element (id_element,id_debtor,insurer)
  2  as
  3  select 1, 1, 'to be updated' from dual union all
  4  select 2, 1, 'to be updated' from dual union all
  5  select 3, 2, 'not to be updated' from dual union all
  6  select 4, 2, 'not to be updated' from dual union all
  7  select 5, 3, 'to be updated' from dual
  8  /

Tabel is aangemaakt.

并且使用您当前的update语句,问题变得很清楚:“不更新”值设置为NULL:

SQL> update
  2      T_ELEMENT elt
  3      set elt.INSURER = (
  4          select HEADER
  5              from T_DEBTOR debtor
  6              where
  7                  debtor.HEADER is not null
  8                  and debtor.ID_DEBTOR = elt.ID_DEBTOR)
  9  /

5 rijen zijn bijgewerkt.

SQL> select * from t_element
  2  /

ID_ELEMENT  ID_DEBTOR INSURER
---------- ---------- -----------------
         1          1 Header 1
         2          1 Header 1
         3          2
         4          2
         5          3 Header 3

5 rijen zijn geselecteerd.

进行此更新的最佳方法是更新两个表的联接。但是有一些限制:

SQL> rollback
  2  /

Rollback is voltooid.

SQL> update ( select elt.insurer
  2                , dtr.header
  3             from t_element elt
  4                , t_debtor dtr
  5            where elt.id_debtor = dtr.id_debtor
  6              and dtr.header is not null
  7         )
  8     set insurer = header
  9  /
   set insurer = header
       *
FOUT in regel 8:
.ORA-01779: cannot modify a column which maps to a non key-preserved table

通过绕过ujvc提示,我们可以规避此限制。但是不建议这样做,除非您真的确定t_debtor.id_debtor是唯一的。

SQL> update /*+ bypass_ujvc */
  2         ( select elt.insurer
  3                , dtr.header
  4             from t_element elt
  5                , t_debtor dtr
  6            where elt.id_debtor = dtr.id_debtor
  7              and dtr.header is not null
  8         )
  9     set insurer = header
 10  /

3 rijen zijn bijgewerkt.

SQL> select * from t_element
  2  /

ID_ELEMENT  ID_DEBTOR INSURER
---------- ---------- -----------------
         1          1 Header 1
         2          1 Header 1
         3          2 not to be updated
         4          2 not to be updated
         5          3 Header 3

5 rijen zijn geselecteerd.

最好只添加一个主键。您可能已经安装了一个:

SQL> rollback
  2  /

Rollback is voltooid.

SQL> alter table t_debtor add primary key (id_debtor)
  2  /

Tabel is gewijzigd.

SQL> update ( select elt.insurer
  2                , dtr.header
  3             from t_element elt
  4                , t_debtor dtr
  5            where elt.id_debtor = dtr.id_debtor
  6              and dtr.header is not null
  7         )
  8     set insurer = header
  9  /

3 rijen zijn bijgewerkt.

SQL> select * from t_element
  2  /

ID_ELEMENT  ID_DEBTOR INSURER
---------- ---------- -----------------
         1          1 Header 1
         2          1 Header 1
         3          2 not to be updated
         4          2 not to be updated
         5          3 Header 3

5 rijen zijn geselecteerd.

问候,罗布。



 类似资料:
  • 问题内容: 我有一个在MySQL中运行良好的查询,但是在Oracle上运行该查询时,出现以下错误: SQL错误:ORA-00933:SQL命令未正确终止 00933。00000-“ SQL命令未正确终止” 查询是: 问题答案: 该语法在Oracle中无效。你可以这样做: 或者您 可以 执行以下操作: 它取决于内联视图是否被Oracle更新( 要更新第二条语句取决于 此处 列出的一些规则 )。

  • 我有一个SQL存储过程,我需要转换为Oracle。我有一些语法问题。 我当前遇到的错误是: 错误(75,1):PLS-00103:在预期以下情况之一时遇到符号“DROP”:(开始情况声明结束异常退出,如果循环mod null pragma raise return选择更新 我想我还有很多。有人能帮我找出我做错了什么吗? 以下是我所拥有的: 以下是原始SQL代码:

  • 我制作了这个简单的GUI程序,它可以计算特定字符序列的元音和辅音。计数器还可以,但是我对if-else语句有一个问题,当那个字符既不是元音也不是辅音时,我必须显示一条消息...代码如下: 它看起来是这样的: 我输入了一个没有任何特殊字符或数字的字符“序列”。但它仍然显示消息,其中它有元音和辅音以外的其他字符。if-else语句有问题吗?感谢您的帮助:)

  • 问题内容: 我不知道是什么问题。使用MySQL 5.0尝试运行以下MYSQL更新语句时出现编译错误 所有字段名称都是正确的。有什么想法吗? 问题答案: 尝试这个: 更新: 既然您说查询产生了语法错误,所以我创建了一些可以对其进行测试的表,并确认查询中没有语法错误: 看到?没有语法错误。我针对MySQL 5.5.8进行了测试。

  • 我有两个表,分别名为tblOefenen(带有主键)和tblOefenen2(带有外键)。我已经删除了前面的外键,因为我想添加‘更新级联’到外键。 那么做了什么:1。我已经移除了TbloeFenen2的约束(外键)。2.我已经将新的外键添加到列ID中,我的主键在列ID上,也在表tbloefenen中: 有人能帮我一下吗?

  • 问题内容: 我从未见过,但是是否可以有一个来自Oracle和SQl Server的SQL调用联接数据? 问题答案: 是的-Oracle和SQL Server均支持链接服务器概念。这样,您就可以使用4个部件名称来引用其他服务器。例如: