该软件包使用Oracle的两个独特功能,REF_CURSOR和包全局变量.我想将功能从Oracle移植到Postgresql或MySQL.
PACKAGE tox IS /*=======================*/ g_spool_key spool.key%TYPE := NULL; TYPE t_spool IS REF CURSOR RETURN spool%ROWTYPE; /*=======================*/ PROCEDURE begin_spool; /*=======================*/ PROCEDURE into_spool ( in_txt IN spool.txt%TYPE ); /*=======================*/ PROCEDURE reset_spool; /*=======================*/ FUNCTION end_spool RETURN t_spool; /*=======================*/ FUNCTION timestamp RETURN VARCHAR2; /*=======================*/ END tox; PACKAGE BODY tox IS /*========================================================================*/ PROCEDURE begin_spool AS /*=======================*/ BEGIN /*=======================*/ SELECT key.NEXTVAL INTO g_spool_key FROM DUAL; /*=======================*/ END begin_spool; /*========================================================================*/ PROCEDURE into_spool ( in_txt IN spool.txt%TYPE ) AS /*=======================*/ BEGIN /*=======================*/ INSERT INTO spool VALUES ( g_spool_key, in_txt, seq.NEXTVAL ); /*=======================*/ END into_spool; /*========================================================================*/ PROCEDURE reset_spool AS /*=======================*/ BEGIN /*=======================*/ DELETE spool WHERE key = g_spool_key; COMMIT; begin_spool; /*=======================*/ END reset_spool; /*========================================================================*/ FUNCTION end_spool RETURN t_spool AS v_spool t_spool; /*=======================*/ BEGIN /*=======================*/ COMMIT; OPEN v_spool FOR SELECT * FROM spool WHERE key = g_spool_key ORDER BY seq; RETURN v_spool; /*=======================*/ END end_spool; /*========================================================================*/ FUNCTION timestamp RETURN VARCHAR2 AS /*-----------------------*/ v_result VARCHAR2(14); /*=======================*/ BEGIN /*=======================*/ SELECT TO_CHAR(SYSDATE,'YYYYMMDDHH24MISS') INTO v_result FROM DUAL; RETURN v_result; /*=======================*/ END timestamp; /*========================================================================*/ END tox;
你能生成相同的代码吗?对于Postgresql?对于MySQL?
注意:Oracle代码是线程安全的.这是一个关键功能.
PostgreSQL 8.3
PostgreSQL中的问题是缺少全局(或包)变量,因此必须使用首先创建的临时表来解决该部分.其余部分非常简单.
如果您认真地将应用程序移植到PostgreSQL或MySQL,我会建议您不要使用全局变量,因为它们在编码时是不好的做法(至少根据我:))
但无论如何,这里是代码:
这必须在运行函数之前存在:
create table spool (key integer, txt varchar(2048), seq integer); create sequence s_key; create sequence s_seq; create schema tox; create temp table globals (name varchar(10), value varchar(100), primary key(name));
这些函数被放在模式tox中以模拟包.
create or replace function tox.get_variable(var_name varchar) returns varchar as $$ declare ret_val varchar(100); begin select value into ret_val from globals where name = var_name; return ret_val; end $$ language plpgsql; create or replace function tox.set_variable(var_name varchar, value anyelement) returns void as $$ begin delete from globals where name = var_name; insert into globals values(var_name, value); end; $$ language plpgsql; create or replace function tox.begin_spool() returns integer as $$ begin perform tox.set_variable('key', nextval('s_key')::varchar); return tox.get_variable('key'); end; $$ language plpgsql; create or replace function tox.reset_spool() returns integer as $$ begin delete from spool where key = tox.get_variable('key')::integer; return tox.begin_spool(); end; $$ language plpgsql; create or replace function tox.into_spool(in_txt spool.txt%TYPE) returns void as $$ begin insert into spool values(tox.get_variable('key')::integer, in_txt, nextval('s_seq')); end; $$ language plpgsql; create or replace function tox.end_spool(refcursor) returns refcursor as $$ declare begin open $1 for select * from spool where key = tox.get_variable('key')::integer order by seq; return $1; end; $$ language plpgsql; create or replace function tox.test(txt varchar(100)) returns setof spool as $$ declare v_spool_key integer; cnt integer; begin v_spool_key = tox.begin_spool(); for cnt in 1..10 loop perform tox.into_spool(txt || cnt); end loop; perform tox.end_spool('spool_cursor'); return query fetch all from spool_cursor; end; $$ language plpgsql;
要测试,只需在创建完所有内容后运行它.
select * from tox.test('Test');