• 可重复执行的SQL Script实战总结


    问题

    在工作中偶尔会遇到这样的问题: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的时候,多一个心思,考虑一下这段代码可否被重复执行,然后根据需要多加一些判断条件,即可以使程序的鲁棒性更好。

  • 相关阅读:
    Active Url 激活URL
    Specified argument was out of the range of valid values.
    EnumHelp
    历史对像(版本对像)
    dom4j API 简介
    即时通讯软件openfire+spark+smack
    openfire插件入门学习
    Openfire本地化配置
    JSONObject与JSONArray的使用
    Android端服务器推送技术原理分析及XMPP的使用
  • 原文地址:https://www.cnblogs.com/maxstack/p/8524528.html
Copyright © 2020-2023  润新知