可重复执行的SQL Script

2018/3/7 21:55:01 人评论 次浏览 分类:Oracle

问题

在工作中偶尔会遇到这样的问题:SQL script重复执行时会报错。

理想的状态下,SQL script跑一遍就够了,是不会重复执行的,但是实际情况往往很复杂。
比如Dev同学在开发时在A环境把他写的那个脚本单独执行了一遍,而在下一个测试周期的时候,测试同学又在A环境把所有DB脚本都执行了一遍,然后就报错了。

如下示例,这里错误的原因在于重复创建表。

例1

create table tableA (col1 char(10), col2 number);

SQL Error: ORA-00955: name is already used by an existing object

再举一个例子,反复执行插入语句虽然可能不会报错(如果没有constraint的话),但是却造成了数据冗余,甚至会影响Data Quality。

例2

insert into tableA values ('ItemA', 10);

原因

这个问题有两个方面的原因:

  • 执行DB脚本的人在不同的的开发周期中往往不是同一个人,且缺乏各个脚本在不同环境的执行记录。
  • DB脚本本身不可(适合)重复执行。

解决方案

解决的方案也有两个方面:

一是规定,Dev一般只在开发环境做测试,如果在其他环境跑了脚本要及时Roll Back。另外,创建一张表,用来记录各个DB脚本在不同环境的执行记录:时间戳,执行人员,成功或失败。

二是写可重复执行的DB Script。比如上面的两个例子可以改成:

例子1-1

declare 
    isexists number;
begin
    select count(*) into isexists from all_tables where table_name='tableA' and owner = 'sysA';
    if isexists = 1 then
        execute immediate 'drop table "sysA"."tableA" purge';
    end if;
    execute immediate 'create table tableA (col1 char(10), col2 number)';
end;

例子2-1

declare 
    countNum number;
begin
    select count(*) into countNum from tableA where col1 = 'ItemA';
    if countNum > 0 then
        delete from tableA where col1 = 'ItemA';
    insert into tableA values ('ItemA', 20);
    end if;
commit;
end;

总的来说,在写DDL或者DML的时候,多一个心思,考虑一下这段代码可否被重复执行,然后根据需要多加一些判断条件,即可以使程序的鲁棒性更好。

相关知识

    暂无相关的知识...

共有访客发表了评论 网友评论

验证码: 看不清楚?