Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.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
Oracle PL/SQL中的异常问题_Oracle_Plsql_Plsqldeveloper - Fatal编程技术网

Oracle PL/SQL中的异常问题

Oracle PL/SQL中的异常问题,oracle,plsql,plsqldeveloper,Oracle,Plsql,Plsqldeveloper,我正在尝试构造一个需要一些异常处理的INSERT INTO查询 以下是迄今为止的代码: declare nvid number := 4561; fromMot number; toMot number; begin for idx in 1..10 loop for fwd in 0..1 loop if fwd=0 then fromMot:=idx; toMot:=8; else fromMot:=8; toMot:=idx;

我正在尝试构造一个需要一些异常处理的INSERT INTO查询

以下是迄今为止的代码:

declare
  nvid number := 4561;
  fromMot number;
  toMot number;
begin
  for idx in 1..10 loop
    for fwd in 0..1 loop

      if fwd=0 then fromMot:=idx; toMot:=8; 
      else fromMot:=8; toMot:=idx; 
      End if;

      insert into MOT_BUFFER_TIME(MBT_ID,MBT_NV_ID,MBT_START_MOT_ID,MBT_END_MOT_ID,MBT_BUFFER_TIME)
      values ((select max(mbt.MBT_ID)+1 from MOT_BUFFER_TIME mbt),nvid,fromMot,toMot,600);
      exception
        when dup_val_on_index then 
          UPDATE MOT_BUFFER_TIME set MBT_BUFFER_TIME=600 where MBT_NV_ID=nvid and MBT_START_MOT_ID=fromMot and MBT_END_MOT_ID=toMot;
    end loop;
  end loop;
end;
/
该表为多个MBT_START_MOT_ID和MBT_END_MOT_ID组合插入了一些缓冲时间,全部为600。这些是n-8和8-n,我选择用嵌套FOR循环来实现

问题在于,该表已经有一些条目,通常是8-5和5-8,它们的值不同,需要更改为600。虽然MBT_ID是主键,但有一个约束条件,即MBT_NV_ID、MBT_START_MOT_ID和MBT_END_MOT_ID的组合必须是唯一的

所以我想我会写一个异常,这样如果有重复的错误,我会更新

问题是PL/SQL开发人员抱怨异常的位置,告诉我它在期待其他东西,还抱怨倒数第二行出现意外循环

很明显我做错了什么,但我看不出是什么。 有什么提示吗?谢谢


编辑:在“值”部分的第一个字段中添加+1,因为如果没有它,它将删除已使用的主键值。

除了实际避免问题之外,例如,如建议的,异常语句应该是代码块的一部分,而您没有,因此您必须添加开始和结束。大概是这样的:

declare
  nvid number := 4561;
  fromMot number;
  toMot number;
begin
  for idx in 1..10 loop
    for fwd in 0..1 loop

      if fwd=0 then fromMot:=idx; toMot:=8; 
      else fromMot:=8; toMot:=idx; 
      End if;

      BEGIN
        insert into MOT_BUFFER_TIME(MBT_ID,MBT_NV_ID,MBT_START_MOT_ID,MBT_END_MOT_ID,MBT_BUFFER_TIME)
        values ((select max(mbt.MBT_ID)+1 from MOT_BUFFER_TIME mbt),nvid,fromMot,toMot,600);
      exception
        when dup_val_on_index then 
          UPDATE MOT_BUFFER_TIME set MBT_BUFFER_TIME=600 where MBT_NV_ID=nvid and MBT_START_MOT_ID=fromMot and MBT_END_MOT_ID=toMot;
      END;
    end loop;
  end loop;
end;
/

编辑以匹配注释中指出的问题编辑。

除了实际避免问题之外(如建议的),异常语句应该是代码块的一部分,而您没有,因此您必须添加开始和结束。大概是这样的:

declare
  nvid number := 4561;
  fromMot number;
  toMot number;
begin
  for idx in 1..10 loop
    for fwd in 0..1 loop

      if fwd=0 then fromMot:=idx; toMot:=8; 
      else fromMot:=8; toMot:=idx; 
      End if;

      BEGIN
        insert into MOT_BUFFER_TIME(MBT_ID,MBT_NV_ID,MBT_START_MOT_ID,MBT_END_MOT_ID,MBT_BUFFER_TIME)
        values ((select max(mbt.MBT_ID)+1 from MOT_BUFFER_TIME mbt),nvid,fromMot,toMot,600);
      exception
        when dup_val_on_index then 
          UPDATE MOT_BUFFER_TIME set MBT_BUFFER_TIME=600 where MBT_NV_ID=nvid and MBT_START_MOT_ID=fromMot and MBT_END_MOT_ID=toMot;
      END;
    end loop;
  end loop;
end;
/

编辑以匹配注释中指出的问题编辑。

使用合并语句查看。异常块必须是开始/结束块中的最后一项。在插入和结束之前添加开始;紧跟在异常处理程序的最后一行之后。并且,是的,请看MERGE语句的使用。不需要以这种方式编写代码。如果使用MERGE,是否意味着首先需要创建一个包含所有要添加的值的临时表?请看MERGE语句的用法。异常块必须是BEGIN/END块中的最后一项。在INSERT和END之前添加BEGIN;紧跟在异常处理程序的最后一行之后。并且,是的,请看MERGE语句的使用。没有必要以这种方式编写代码。如果我使用MERGE,这是否意味着我首先需要创建一个包含所有要添加的值的临时表?这就是它不起作用的原因-谢谢。虽然我已经编辑了我的原始问题,因为值部分的第一个字段需要选择maxmbt.MBT_ID+1 from MOT_BUFFER_TIME MBT才能获得一个免费的主键!这就是它不起作用的原因-谢谢。虽然我已经编辑了我的原始问题,因为值部分的第一个字段需要选择maxmbt.MBT_ID+1 from MOT_BUFFER_TIME MBT才能获得一个免费的主键!