【问题标题】:Creating multiple updates on database with procedure. Problem with incrementation使用过程在数据库上创建多个更新。增量问题
【发布时间】:2019-08-05 17:24:55
【问题描述】:

我正在尝试在 oracle sql 中创建一个过程,以便对一个表进行多次更新。对于不同的值,我有大约 500 次更新,但我只更改一列是唯一的,它的任务是对行进行编号。所以我想将数字 20 更改为 21,依此类推,直到数字 120。所以最后数字 20 将是​​空的,我将有 121 行。

我创建了这个循环,但我不断收到错误“违反唯一约束”,所以我认为我的迭代不起作用。

declare 
n integer := 20;
BEGIN
    FOR x in 20..120  LOOP
    Update my_table
    SET number_of_field = n WHERE number_of_field > 20;
    n:= n + 1;
      END LOOP;
      END;

我非常感谢帮助,因为这是我第一次在 SQL 中使用过程,我会觉得我已经接近解决方案了。 谢谢!

【问题讨论】:

  • 如果你想将 1 添加到行的子集,并且你可以控制行重新编号的顺序,我会从 120 开始下降到 20。这样我永远不会产生重复的行号。

标签: sql for-loop plsql


【解决方案1】:

Oracle 是少数允许您将约束检查推迟到事务结束的数据库之一(PostgreSQL 是另一个 afaik)。

如果您将整个代码块放入单个事务中,并将 UNIQUE 约束的检查推迟到DEFERRABLE INITIALLY DEFERRED,那么您可以在其中执行所有更新,即使您暂时在列中存储重复值。但是,一旦您执行COMMIT,将验证约束(适用于所有行/更新),如果失败,事务将回滚。因此,一旦发出提交,您需要保持良好的立场。

例如,您可以将表格更改为:

create table my_table (
  ... other_columns here
  number_of_field,
  constraint uq1 unique(number_of_field) deferrable initially deferred
);

【讨论】:

  • 非常感谢您的回答,但不幸的是我无法更改表格特征,因为我正在这样做是为了工作。您还有其他想法吗?
【解决方案2】:

我是这样理解这个问题的:

SQL> -- Create table
SQL> create table my_table (number_of_field number, somecol varchar2(10));

Table created.

SQL> -- Insert sample data; my end with 30, not 120 (that's too much for an example)
SQL> insert into my_table
  2    select 20 + level - 1, 'X'
  3      from dual
  4      connect by level <= 11;

11 rows created.

SQL> -- Table contents
SQL> select number_of_field, somecol from my_table order by number_of_field nulls first;

NUMBER_OF_FIELD SOMECOL
--------------- ----------
             20 X
             21 X
             22 X
             23 X
             24 X
             25 X
             26 X
             27 X
             28 X
             29 X
             30 X

11 rows selected.

两步工作:更新现有行(通过添加 1)并插入一个空行(somecol 在这里只是为了表明有一行带有空的number_of_Field 列)。

SQL> -- Update existing rows; insert an "empty" one
SQL> begin
  2    update my_table set
  3      number_of_field = number_of_field + 1;
  4    insert into my_table (number_of_field, somecol)
  5      values (null, 'X');
  6  end;
  7  /

PL/SQL procedure successfully completed.

SQL> -- The result
SQL> select number_of_field, somecol from my_table order by number_of_field nulls first;

NUMBER_OF_FIELD SOMECOL
--------------- ----------
                X
             21 X
             22 X
             23 X
             24 X
             25 X
             26 X
             27 X
             28 X
             29 X
             30 X
             31 X

12 rows selected.

SQL>

【讨论】:

  • 很遗憾,update my_table set number_of_field = number_of_field + 1; 的声明可能会失败。创建表时,您没有包含唯一约束 constraint uq1 unique (number_of_field)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-06
  • 2011-10-17
  • 1970-01-01
  • 1970-01-01
  • 2016-01-15
  • 1970-01-01
相关资源
最近更新 更多