41.13. 에서 포팅Oracle토토 사이트/sql#

이 섹션은의 차이점을 설명합니다.PostgreSQL's토토 사이트/pgsql언어 및 Oracle 's토토 사이트/sql언어, 응용 프로그램을 포트하는 개발자를 돕기 위해Oracle® toPostgreSQL.

토토 사이트/pgsql는 여러 측면에서 PL/SQL과 유사합니다. 블록 구조화되고 명령적인 언어이며 모든 변수를 선언해야합니다. 과제, 루프 및 조건부는 비슷합니다. 포팅 할 때 명심해야 할 주요 차이점토토 사이트/sqlto토토 사이트/pgsqlare :

  • SQL 명령에 사용 된 이름이 명령에 사용되는 테이블의 열 이름이거나 함수 변수에 대한 참조토토 사이트/sql열 이름으로 취급합니다. 기본적으로토토 사이트/pgsql이름이 모호하다고 불평하는 오류가 발생합니다. 지정할 수 있습니다토토 사이트pgsql.variable_conflict=use_column일치하도록이 동작을 변경하려면PL/SQL, 설명 된대로섹션 41.11.1. 처음에는 그러한 모호성을 피하는 것이 가장 좋습니다. 그러나이 동작에 의존하는 많은 양의 코드를 포트 해야하는 경우variable_conflict최상의 솔루션 일 수 있습니다.

  • inPostgreSQL함수 본문은 문자열 문자로 작성되어야합니다. 따라서 기능 본문에서 달러 인용문을 사용하거나 단일 따옴표를 탈출해야합니다. (보다섹션 41.12.1.)

  • 데이터 유형 이름은 종종 번역이 필요합니다. 예를 들어, Oracle String에서 값은 일반적으로 유형으로 선언됩니다varchar2, 비 SQL 표준 유형입니다. 안에PostgreSQL, 유형 사용Varchar또는텍스트대신. 마찬가지로 유형을 대체합니다번호with숫자또는 더 적절한 데이터 유형이있는 경우 다른 숫자 데이터 유형을 사용하십시오.

  • 패키지 대신 스키마를 사용하여 기능을 그룹으로 구성하십시오.

  • 패키지가 없으므로 패키지 수준 변수도 없습니다. 이것은 다소 성가시다. 세션 당 상태를 대신 임시 테이블로 유지할 수 있습니다.

  • Integerfor루프Reverse다르게 작업 :토토 사이트/sql두 번째 숫자에서 첫 번째 숫자로 카운트 다운,토토 사이트/pgsql첫 번째 숫자에서 두 번째 숫자로 카운트 하락하여 포팅 할 때 루프 경계를 교환해야합니다. 이 비 호환성은 불행하지만 변경되지는 않을 것입니다. (보다섹션 41.6.5.5.)

  • for쿼리를 통한 루프 (커서 제외)도 다르게 작동합니다. 대상 변수가 선언되었지만토토 사이트/sql항상 암시 적으로 선언합니다. 이것의 장점은 루프 종료 후에도 가변 값이 여전히 액세스 할 수 있다는 것입니다.

  • 커서 변수 사용에는 다양한 표기법 차이가 있습니다.

41.13.1. 포팅 예제#

예 41.9간단한 기능을 포트하는 방법을 보여줍니다토토 사이트/sqlto토토 사이트/pgsql.

예 41.9. 에서 간단한 기능 포팅토토 사이트/sqlto토토 사이트/pgsql

여기에Oracle PL/SQL기능 :

함수 생성 또는 교체 CS_FMT_BROWSER_VERSION (v_name varchar2,
                                                  v_version varchar2)
반환 varchar2입니다
시작하다
    v_version이 null이면 그렇다면
        반환 v_name;
    끝 IF;
    반환 v_name || '/'|| v_version;
끝;
/
오류 표시;

이 기능을 살펴보고에 비해 차이점을 보자.토토 사이트/pgsql:

  • 유형 이름varchar2|Varchar또는텍스트. 이 섹션의 예에서 우리는를 사용할 것입니다.Varchar그러나텍스트특정 문자열 길이 한계가 필요하지 않으면 종종 더 나은 선택입니다.

  • thereturn함수 프로토 타입의 키워드 (기능 본문이 아님)가됩니다반환inPostgreSQL. 또한,isas언어절로토토 사이트/pgsql유일한 기능 언어는 아닙니다.

  • inPostgreSQL, 함수 본문은 문자열 문자로 간주되므로 그 주변의 견적 표시 또는 달러 인용문을 사용해야합니다. 이것은 종료를 대신합니다/Oracle 접근법에서.

  • the오류 표시명령이 존재하지 않습니다PostgreSQL, 오류가 자동으로보고되어 필요하지 않습니다.

이것은이 기능이 포팅되었을 때 어떻게 보이는지입니다.PostgreSQL:

함수 작성 또는 교체 CS_FMT_BROWSER_VERSION (V_NAME VARCHAR,
                                                  v_version varchar)
Varchar를 $$로 반환합니다
시작하다
    v_version이 null이면 그렇다면
        반환 v_name;
    끝 IF;
    반환 v_name || '/'|| v_version;
끝;
$$ 언어 plpgsql;

예 41.10다른 함수를 생성하는 함수를 포트하는 방법과 그에 따른 인용 문제를 처리하는 방법을 보여줍니다.

예 41.10. 에서 다른 함수를 생성하는 함수 포팅토토 사이트/sqlto토토 사이트/pgsql

다음 절차는 a에서 행을 잡습니다.select명령문과 결과와 함께 큰 기능을 구축합니다.if진술, 효율성을위한 진술.

이것은 Oracle 버전입니다 :

프로 시저 생성 또는 교체 CS_UPDATE_REFERRER_TYPE_PROC IS
    Cursor referrer_keys입니다
        CS_REFERRER_KEYS에서 *를 선택하십시오
        try_order의 주문;
    func_cmd varchar (4000);
시작하다
    func_cmd : = '함수 생성 또는 교체 CS_FIND_REFERRER_TYPE (v_host in varchar2,
                 varchar2의 v_domain, varchar2의 v_url) return varchar2가 시작됩니다. ';

    referrer_key의 경우 referrer_keys 루프
        func_cmd : = func_cmd ||
          'V_'|| referrer_key.kind
          || '좋아요' ''|| referrer_key.key_string
          || ````그런 다음 반환 '' '|| referrer_key.referrer_type
          || '' ';; 끝 If; ';
    엔드 루프;

    func_cmd : = func_cmd || '귀환 널; 끝;';

    즉시 func_cmd를 실행합니다.
끝;
/
오류 표시;

이 기능이 어떻게 끝나는 지PostgreSQL:

절차 작성 또는 교체 CS_UPDATE_REFERRER_TYPE_PROC ()는 $ func $로
선언하다
    참조 _keys 커서입니다
        CS_REFERRER_KEYS에서 *를 선택하십시오
        try_order의 주문;
    func_body 텍스트;
    func_cmd 텍스트;
시작하다
    func_body : = '시작';

    referrer_key의 경우 referrer_keys 루프
        func_body : = func_body ||
          'V_'|| referrer_key.kind
          || '좋아요'|| quote_literal (referrer_key.key_string)
          || '그런 다음 반환'|| quote_literal (referrer_key.referrer_type)
          || ';; 끝 If; ' ;
    엔드 루프;

    func_body : = func_body || '귀환 널; 끝;';

    func_cmd : =
      '기능 생성 또는 교체 CS_FIND_REFERRER_TYPE (V_HOST VARCHAR,
                                                        v_domain varchar,
                                                        v_url varchar)
        varchar를 '로 반환합니다.
      || quote_literal (func_body)
      || '언어 plpgsql;' ;

    func_cmd를 실행합니다.
끝;
$ func $ language plpgsql;

함수의 본문이 어떻게 별도로 만들어지고 통과되는지 알 수 있습니다QUOTE_LITERAL그 안에 인용 표시를 두 배로 늘리려면. 이 기술은 새로운 기능을 정의하기 위해 안전하게 달러 인용을 사용할 수 없기 때문에 필요합니다.referrer_key.key_string필드. (우리는 여기서 그것을 가정하고 있습니다referrer_key.kind항상 신뢰할 수 있습니다host, 도메인또는URL하지만referrer_key.key_string22969_23148referrer_key.key_string또는referrer_key.referrer_type견적 표시 포함.


예 41.11|out매개 변수 및 문자열 조작.PostgreSQL내장이 없습니다instr함수이지만 다른 함수의 조합을 사용하여 하나를 만들 수 있습니다. 안에섹션 41.13.3aPL/PGSQL구현instr포팅을 더 쉽게하기 위해 사용할 수 있습니다.

예 41.11. 문자열 조작으로 절차 포팅 및out매개 변수PL/SQLto토토 사이트/pgsql

다음OraclePL/SQL 절차는 URL을 구문 분석하고 여러 요소 (호스트, 경로 및 쿼리)를 반환하는 데 사용됩니다.

이것은 Oracle 버전입니다 :

절차 작성 또는 교체 CS_PARSE_URL (
    Varchar2의 v_url,
    v_host out varchar2 - 이것은 다시 전달됩니다
    V_PATH OUT VARCHAR2 - 이것도
    v_query out varchar2) - 그리고 이것
이다
    A_POS1 정수;
    A_POS2 정수;
시작하다
    v_host : = null;
    v_path : = null;
    v_query : = null;
    a_pos1 : = inst (v_url, '//');

    A_POS1 = 0이면
        반품;
    끝 IF;
    a_pos2 : = inst (v_url, '/', a_pos1 + 2);
    a_pos2 = 0이면
        v_host : = substr (v_url, a_pos1 + 2);
        v_path : = '/';
        반품;
    끝 IF;

    v_host : = substr (v_url, a_pos1 + 2, a_pos2 -a_pos1-2);
    a_pos1 : = inst (v_url, '?', a_pos2 + 1);

    A_POS1 = 0이면
        v_path : = substr (v_url, a_pos2);
        반품;
    끝 IF;

    v_path : = substr (v_url, a_pos2, a_pos1 -a_pos2);
    v_query : = substr (v_url, a_pos1 + 1);
끝;
/
오류 표시;

여기에 가능한 번역이 있습니다토토 사이트/pgsql:

함수 작성 또는 교체 CS_PARSE_URL (
    Varchar의 v_url,
    V_HOST OUT VARCHAR-- 이것은 다시 전달됩니다
    V_PATH OUT VARCHAR- - 이것도
    v_query out varchar) - 그리고 이것
$$로
선언하다
    A_POS1 정수;
    A_POS2 정수;
시작하다
    v_host : = null;
    v_path : = null;
    v_query : = null;
    a_pos1 : = inst (v_url, '//');

    A_POS1 = 0이면
        반품;
    끝 IF;
    a_pos2 : = inst (v_url, '/', a_pos1 + 2);
    a_pos2 = 0이면
        v_host : = substr (v_url, a_pos1 + 2);
        v_path : = '/';
        반품;
    끝 IF;

    v_host : = substr (v_url, a_pos1 + 2, a_pos2 -a_pos1-2);
    a_pos1 : = inst (v_url, '?', a_pos2 + 1);

    A_POS1 = 0이면
        v_path : = substr (v_url, a_pos2);
        반품;
    끝 IF;

    v_path : = substr (v_url, a_pos2, a_pos1 -a_pos2);
    v_query : = substr (v_url, a_pos1 + 1);
끝;
$$ 언어 plpgsql;

이 기능은 다음과 같이 사용할 수 있습니다.

select * from cs_parse_url ( 'http://foobar.com/query.cgi?baz');

예 41.12Oracle과 관련된 수많은 기능을 사용하는 절차를 포트하는 방법을 보여줍니다.

예 41.12. 절차 포팅토토 사이트/sqlto토토 사이트/pgsql

Oracle 버전 :

절차 작성 또는 교체 CS_CREATE_JOB (v_JOB_ID Integer)는 IS입니다
    a_running_job_count 정수;
시작하다
    독점 모드에서 잠금 테이블 CS_JOBS;

    end_stamp가 null 인 cs_jobs에서 a_running_job_count로 count (*)를 선택하십시오.

    a_running_job_count 0 인 경우
        저지르다; - 무료 잠금
        REAS_APPLICATION_ERROR (-20000,
                 '새로운 직업을 만들 수 없음 : 현재 일자리가 실행 중입니다.');
    끝 IF;

    cs_active_job에서 삭제;
    cs_active_job (job_id) 값 (v_job_id)에 삽입;

    시작하다
        cs_jobs (job_id, start_stamp) 값 (v_job_id, now ())에 삽입;
    예외
        dup_val_on_index 일 때 null; - 이미 존재하는지 걱정하지 마십시오
    끝;
    저지르다;
끝;
/
오류 표시

이것이 우리 가이 절차를 포트 할 수있는 방법입니다토토 사이트/pgsql:

절차 작성 또는 교체 CS_CREATE_JOB (V_JOB_ID Integer)를 $$
선언하다
    a_running_job_count 정수;
시작하다
    독점 모드에서 잠금 테이블 CS_JOBS;

    end_stamp가 null 인 cs_jobs에서 a_running_job_count로 count (*)를 선택하십시오.

    a_running_job_count 0 인 경우
        저지르다; - 무료 잠금
        예외 제외 '새 작업을 만들 수 없음 : 현재 작업이 실행 중입니다'; -(1)
    끝 IF;

    cs_active_job에서 삭제;
    cs_active_job (job_id) 값 (v_job_id)에 삽입;

    시작하다
        cs_jobs (job_id, start_stamp) 값 (v_job_id, now ())에 삽입;
    예외
        고유 한 _violation-(2)
            - 이미 존재하는지 걱정하지 마십시오
    끝;
    저지르다;
끝;
$$ 언어 plpgsql;

(1)

의 구문Rain기본 사례이지만 Oracle의 진술과 상당히 다릅니다Raine Exception_name비슷하게 작동합니다.

(2)

예외 이름이 지원하는PL/PGSQL는 Oracle 's와 다릅니다. 내장 예외 이름 세트가 훨씬 큽니다 (PostgreSQL : 문서 : 17 : 부록 A. PostgreSQL 토토 꽁 머니 코드). 사용자가 선택한 SQLSTATE 값을 대신 던질 수 있지만 현재 사용자 정의 예외 이름을 선언하는 방법은 없습니다.


41.13.2. 지켜봐야 할 다른 것들#

이 섹션은 Oracle을 포팅 할 때 볼 수있는 다른 몇 가지 사항을 설명합니다토토 사이트/sql함수PostgreSQL.

41.13.2.1. 예외 후 암시 적 롤백#

in토토 사이트/pgsql, 예외가 AN에 의해 ​​잡히면예외조항, 블록 이후 모든 데이터베이스 변경시작자동으로 롤백됩니다. 즉, 행동은 다음과 같이 오라클에서 얻는 것과 동일합니다.

시작
    SavePoint S1;
    ... 여기 코드 ...
예외
    언제 ... 그럼
        S1 롤백;
        ... 여기 코드 ...
    언제 ... 그럼
        S1 롤백;
        ... 여기 코드 ...
끝;

사용하는 Oracle 절차를 번역하는 경우SavePointand롤백으로이 스타일에서는 작업이 쉽습니다.SavePointand롤백으로. 사용하는 절차가있는 경우SavePointand롤백으로다른 방식으로 실제 생각이 필요할 것입니다.

41.13.2.2. execute #

the토토 사이트/pgsql버전executePL/SQL버전이지만 사용하는 것을 기억해야합니다quote_literalandQUOTE_INDEN설명대로섹션 41.5.4. 유형의 구성execute 'select * from $ 1';이 함수를 사용하지 않으면 안정적으로 작동하지 않습니다.

41.13.2.3. 최적화토토 사이트/pgsql기능#

PostgreSQL실행을 최적화하기 위해 두 가지 기능 생성 수정자를 제공합니다.변동성(동일한 인수가 주어진 경우 함수가 항상 동일한 결과를 반환하는지 여부) 및엄격함(인수가 null이면 함수가 null을 반환하는지 여부). 상담함수 만들기자세한 내용 참조 페이지.

이러한 최적화 속성을 사용할 때함수 만들기진술은 다음과 같이 보일 수 있습니다 :

함수 생성 foo (...)는 정수를 $$로 반환합니다
...
$$ 언어 plpgsql 엄격한 불변성;

41.13.3. 충수#

이 섹션은 Oracle과 호환성 세트에 대한 코드가 포함되어 있습니다instr포팅 노력을 단순화하는 데 사용할 수있는 기능.

-
- Oracle의 상대를 모방하는 기기 기능
- 구문 : instr (String1, String2 [, n [, m]]))
- 여기서 []는 선택적 매개 변수를 나타냅니다.
-
-Mth 발생을 위해 Nth 캐릭터에서 시작하여 string1을 검색합니다.
- String2.  N이 음수이면 ABS (N)에서 시작하여 뒤로 검색합니다.
- 문자열 끝의 문자 1.
-N이 통과되지 않으면 1을 가정하십시오 (검색이 첫 번째 문자에서 시작).
- M이 통과되지 않으면 1을 가정하십시오 (첫 번째 발생을 찾으십시오).
- String1에서 String2의 시작 인덱스 또는 String2를 찾을 수없는 경우 0을 반환합니다.
-

기능 악기 (Varchar, Varchar)를 작성하십시오. 정수를 $$로 반환합니다
시작하다
    반품 기기 ($ 1, $ 2, 1);
끝;
$$ 언어 plpgsql 엄격한 불변;

기능 악기 생성 (String varchar, String_to_search_for varchar,
                      beg_index 정수)
정수를 $$로 반환합니다
선언하다
    POS 정수 NOL NULL DEFAULT 0;
    temp_str varchar;
    정수를 구걸하십시오.
    길이 정수;
    ss_length 정수;
시작하다
    beg_index 0이면
        temp_str : = substring (beg_index의 문자열);
        pos : = 위치 (temp_str의 String_to_search_for);

        POS = 0이면
            반환 0;
        또 다른
            POS + BEG_INDEX를 반환합니다 -1;
        끝 IF;
    elsif beg_index <0
        ss_length : = char_length (string_to_search_for);
        길이 : = char_length (문자열);
        beg : = 길이 + 1 + beg_index;

        beg 0 루프
            temp_str : = 서브 스트링 (ss_length의 beg에서 문자열);
            string_to_search_for = temp_str if then
                반환 구걸;
            끝 IF;

            Beg : = Beg -1;
        엔드 루프;

        반환 0;
    또 다른
        반환 0;
    끝 IF;
끝;
$$ 언어 plpgsql 엄격한 불변;

기능 악기 생성 (String varchar, String_to_search_for varchar,
                      beg_index 정수, cose_index 정수)
정수를 $$로 반환합니다
선언하다
    POS 정수 NOL NULL DEFAULT 0;
    alkes_number 정수 NOL NULL DEFAULT 0;
    temp_str varchar;
    정수를 구걸하십시오.
    나는 정수;
    길이 정수;
    ss_length 정수;
시작하다
    발생하면 _index <= 0
        'Argument' '%' '는 범위를 벗어났습니다.'
          errcode 사용 = '22003';
    끝 IF;

    beg_index 0이면
        beg : = beg_index -1;
        1. Occur_index 루프
            temp_str : = 서브 스트링 (beg + 1의 문자열);
            pos : = 위치 (temp_str의 String_to_search_for);
            POS = 0이면
                반환 0;
            끝 IF;
            beg : = beg + pos;
        엔드 루프;

        반환 구걸;
    elsif beg_index <0
        ss_length : = char_length (string_to_search_for);
        길이 : = char_length (문자열);
        beg : = 길이 + 1 + beg_index;

        beg 0 루프
            temp_str : = 서브 스트링 (ss_length의 beg에서 문자열);
            string_to_search_for = temp_str if then
                alkes_number : = alkes_number + 1;
                alke_number = cose_index가있는 경우
                    반환 구걸;
                끝 IF;
            끝 IF;

            Beg : = Beg -1;
        엔드 루프;

        반환 0;
    또 다른
        반환 0;
    끝 IF;
끝;
$$ 언어 plpgsql 엄격한 불변성;

수정 제출

문서에 올바르지 않은 내용이 있으면 일치하지 않습니다. 특정 기능에 대한 귀하의 경험 또는 추가 설명이 필요합니다. 사용이 양식문서 문제를보고하려면