寻找一种方法来更新模式中所有表的主键列的最小值,我能够从所需的模式中获取主键列名称和表名称的值,但不确定如何使用该选择使用 PLSQL 查询输出来更新值
无法找到解决问题的正确方法
为什么要更新主键列值?您确定这是个好主意吗?因为,
无论如何:这里的示例展示了如何做到这一点 - 动态 SQL。阅读代码中的注释。
在我的示例架构中,有几个带有主键的表:
SQL> select c.table_name, c.column_name, p.data_type
2 from user_cons_columns c join
3 user_constraints t on t.constraint_name = c.constraint_name join
4 user_tab_columns p on p.table_name = c.table_name
5 and p.column_name = c.column_name
6 where t.constraint_type = 'P';
TABLE_NAME COLUMN_NAME DATA_TYPE
--------------- --------------- ---------------
DEPT DEPTNO NUMBER --> foreign key from EMP won't allow update
EMP EMPNO NUMBER
COUNTRIES CODE VARCHAR2 --> datatype will rule out this PK
TEST ID NUMBER
好的,我们走吧:
SQL> set serveroutput on
SQL> declare
2 l_str varchar2(200);
3 l_old_pk_value number;
4 l_new_pk_value number := -1;
5 begin
6 -- find primary keys whose datatype is NUMBER on position 1
7 for cur_r in (select c.table_name, c.column_name
8 from user_cons_columns c join
9 user_constraints t on t.constraint_name = c.constraint_name join
10 user_tab_columns p on p.table_name = c.table_name
11 and p.column_name = c.column_name
12 where t.constraint_type = 'P'
13 and p.data_type = 'NUMBER'
14 and c.position = 1)
15 loop
16 dbms_output.put_line('Working on ' || cur_r.table_name ||'.'|| cur_r.column_name);
17 -- find minimum value of primary key column
18 l_str := 'select min(' || cur_r.column_name ||')' ||
19 ' from ' ||cur_r.table_name;
20 execute immediate l_str into l_old_pk_value;
21
22 -- update minimum value of the primary key column to L_NEW_PK_VALUE
23 l_str := 'update ' || cur_r.table_name || ' set ' ||
24 cur_r.column_name || ' = ' || l_new_pk_value ||
25 ' where ' ||cur_r.column_name || ' = ' || l_old_pk_value;
26 -- report if something goes wrong
27 begin
28 execute immediate l_str;
29 exception
30 when others then
31 dbms_output.put_line(cur_r.table_name ||'.'|| cur_r.column_name ||': '|| sqlerrm);
32 end;
33 end loop;
34 end;
35 /
结果:
Working on DEPT.DEPTNO
DEPT.DEPTNO: ORA-02292: integrity constraint (SCOTT.FK_EMP_DEPT) violated - child record found
Working on EMP.EMPNO
Working on TEST.ID
PL/SQL procedure successfully completed.
正如我所说,
DEPT
在外键约束上失败了。 EMP
和 TEST
已更新。
SQL> select * from emp where empno = -1;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
-1 SMITH CLERK 7902 17-DEC-80 800 20
SQL> select * From test;
ID NAME
---------- --------------------
-1 Littlefoot
2 Bigfoot
SQL>