2

このパッケージは、Oracle の 2 つの固有の機能である 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 コードはスレッドセーフです。これは重要な機能です。

4

4 に答える 4

6

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');
于 2009-02-05T16:54:57.203 に答える
-1

mysql の場合:

  1. ref_cursor の場合、プロシージャで通常の選択を使用できます。MySQL には、select ステートメントを発行した場合にストアド プロシージャから返される暗黙的な結果セットがあります。ここで私の答えを見てください。
  2. パッケージのグローバル変数については、テーブルに入れることができますが、コードからはシーケンスであると思われるため、auto_increment フィールドに置き換えることができます。それはかなり単純なはずです。

質問にスプールテーブルの定義を投稿していただけると助かります。そうすれば、mysql の正確なコードを提供できると思います。

于 2009-01-31T22:40:07.433 に答える