• 数据库迁移-国产化-Oracle迁移至GBase8a(存储过程)


    1. 创建语法

    下表介绍了 GBase 8a 和Oracle 存储过程的创建语法。

    数据库

    语法

    GBase 8a

    CREATE PROCEDURE ``.``

    (  [ IN | OUT | INOUT ] [param_name] [type] )

    BEGIN 

     /* 语句 */

    END

    Oracle

     CREATE OR REPLACE PROCEDURE MyProName IS
     BEGIN
     NULL;
     END;

    下面给出一个创建存储过程的示例:

    数据库

    示例

    GBase 8a

    CREATE PROCEDURE temp_proc ( p_id int )

    BEGIN

    declare User_id NUMBER;

    select name from user where id = p_id;

    END;

    Oracle

    CREATE PROCEDURE temp_proc (p_id NUMBER)

    AS

    User_id NUMBER;

    BEGIN

    select name from user where id = p_id; 

    END;

    /

    2. 参数的默认值

    GBase 8a ,参数没有默认值,且调用时不可以省略参数,如果参数无值可是输入 null , Oracle 可以为参数设默认值,且可以省略有默认值的参数

    示例:

    数据库

    示例

    GBase 8a

    没有此功能

    Oracle

    CREATE PROCEDURE temp_proc ( p_id number  := 1)

    3. 定义临时变量

    GBase 8a:

    DECLARE语句用来定义各种程序的局部项:局部变量, 条件和处理器以及游标,DECLARE只能被用在BEGIN ... END复合语句之间,且必须位于其它语句之前的开始处,游标必须在声明处理器和变量之前被声明,并且条件必须在声明游标或处理器前声明,命名可以任意(不能使用GBase 8a关键字),每个DECLARE必须以;来结束。

    Oracle:

    直接定义变量。

    例:

    GBase 8a: DECLARE p_name varchar(32) defualt 'abc';

    Oracle: User_id varchar(32) :='abc';

    4. if 语句

    语法格式不同:

    GBase 8a: IF search_condition THEN statement_list

    [ELSEIF search_condition THEN statement_list] ...

    [ELSE statement_list]

    END IF

    Oracle:IF search_condition THEN statement_list

    [ELSIF search_condition THEN statement_list] ...

    [ELSE statement_list]

    END IF

    示例:  

    数据库

    示例

    GBase 8a

    if( flag = 0) then

    set name = 'aa';

    elseif( flag = 1 ) then

    set name = 'bb';

    else

    set name = 'cc';

    end if;

    Oracle

    IF flag = 0 THEN

    name := 'aa';

    ELSIF flag = 1 then

    name := 'bb';

    ELSE

    name := ‘cc’

    END IF;

    5. while 语句

    有循环应该放在一起写

    语法:

    数据库

    语法

    GBase 8a

    [begin_label:] WHILE search_condition DO

    statement_list

    END WHILE [end_label]

    Oracle

    <>

    WHILE condition LOOP

       sequence_of_statements

    END LOOP;

    解释:

    只要search_condition为真,WHILE语句中的一个或多个语句就被重复执行。 WHILE可以加标号。只有当begin_label 出现时才能有end_label ,并且如果两个都存在,必须相同。

    对于Oracle使用 EXIT ,GBase 8a使用LEAVE语句,

    语法: LEAVE label

    这条语句用来退出任何有标号的流控制构造。它可以用在 BEGIN ... END 或循环中。

    对于跳过 (CONTINUE) ,GBase 8a 使用 ITERATE 语句,Oracle 可以使用 goto 也可以用 if  结构加以限制。

    语法: ITERATE label

    ITERATE只能出现在LOOP, REPEAT, 和WHILE语句中。ITERATE 意味着“再一次循环。”

    示例:

    数据库

    示例

    GBase 8a

    while_label:while( i<10 ) do

    i++;

    if( i%2 >0 ) then

    ITERATE while_label;

    end if;

    set temp_str = concat( temp_str, ',' ,i );

    if( i = 8 ) then

       LEAVE while_label;

    end if;

    end while while_label;

    Oracle

    <>

    WHILE i <= 10 LOOP

    i:=i+1;

    if mod(i,2) >0  then

    goto loop_statr;

    end if;

    temp_str := temp_str || ',' || to_char(i) ;

    if( i = 8 ) then

    exit;

    end if;

    END LOOP;

    6. 游标

    GBase 8a: 存储过程和函数中支持游标。语法就像是嵌入式SQL。游标是未知的,只读的和不能滚动的。未知意味着服务器可能对它的结果表做一个拷贝,也可能不做。

    游标必须在声明处理器之前被声明,变量和条件必须在声明游标或处理器之前被声明。

    示例:

    Oracle

    GBase 8a

    CREATE OR REPLACE PROCEDURE hr.testProc IS

    my_sal hr.employees.salary%TYPE;

    my_job hr.employees.job_id%TYPE;

    factor INTEGER := 2;

    CURSOR c1 IS

    SELECT factor*salary FROM hr.employees WHERE job_id = my_job;

    BEGIN

    my_job := 'IT_PROG';

    OPEN c1;  --打开游标

    LOOP

    FETCH c1 INTO my_sal;

    EXIT WHEN c1%NOTFOUND;

    factor := factor + 1;  -- does not affect FETCH

    END LOOP;

    DBMS_OUTPUT.PUT_LINE(factor);

    END;

    /

    CREATE PROCEDURE testProc()

    BEGIN

    DECLARE my_sal DOUBLE;

    DECLARE my_job varchar(10);

    DECLARE factor int DEFAULT 2;

    DECLARE done int DEFAULT 0;

    DECLARE c1 CURSOR FOR

    SELECT factor*salary FROM employees WHERE job_id = my_job;

    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

    set my_job = 'IT_PROG';

    OPEN c1;  -- 打开游标

    ll:LOOP

    FETCH c1 INTO my_sal;

    if( done = 1 )then

    LEAVE ll; --退出循环

    end if;

    set factor = factor + 1;  -- does not affect FETCH

    END LOOP ll;

    select factor;

    END

    |

    需要注意的是GBase 8a中判断游标执行到最后,是使用定义一个异常处理来判断的。DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;当游标指针指导最后一个未知,就会触发一个异常,通过捕获这个异常,将变量 done 值变为 1 。

    7. 管道表迁移

    这个需要根据不同的场景进行合理的改造。或借助临时表,或得到结果后直接返回字符串,或者借助其他方法。

    关于管道表的迁移,没有肯定的改造方法。

    8. for循环

    一般的for循环,可以借助while或repeat迁移。但如果for使用的是类似shell脚本中for,循环条件为类似枚举类型或结果集,那么就需要根据需要是否变成一个游标代替,或寻找其他方案。

    9. 异常捕捉

    GBase 8a支持对存储过程中的异常捕捉,形式如下:

    Declare {exit|continue } handler for {sqlexception | not found | sqlstate ‘02000’}

    sqlstate后面为GBase 8a的错误代码,也就是说可以针对性的捕捉任一异常。

  • 相关阅读:
    Nginx部署history路由模式的vue项⽬
    docker 部署 subversion
    如何阅读论文?
    静态HTML CSS个人网页作业源代码 (人物介绍)
    即刻报名,企业服务与新经济论坛亮点提前揭秘!
    附录1-爬虫的一些技巧
    Linux、docker、kubernetes、MySql、Shell运维快餐
    《Python编程:从入门到实践》第19章笔记:用户/用户注册/身份验证
    springBoot框架简介入门教程(快速学习版)
    第一节:vue3 配置路由
  • 原文地址:https://blog.csdn.net/huixinhuiyismile/article/details/126297545