이 문서는 지원되지 않는 버전의 PostgreSQL을위한 것입니다.
당신은에 대해 같은 페이지를 볼 수 있습니다PostgreSQL : 문서 : 17 : 41.13. Oracle 토토 사이트/SQL에서 포팅버전 또는 위에 나열된 다른 지원되는 버전 중 하나입니다.

19.11. 오라클에서 포팅 PL/SQL

저자 :Roberto Mello ()

이 섹션은 Oracle의 PL/SQL과의 차이점을 설명합니다.PostgreSQL's토토 핫/pgsql도움을 희망하는 언어 개발자 포트 응용 프로그램 Oracle에서PostgreSQL. 여기의 대부분의 코드는 왔습니다 그만큼arsdigita ClickStream 모듈내가 포팅 한PostgreSQL내가 인턴쉽을했을 때OpenForce Inc.2000 년 여름.

토토 핫/pgsqlPL/SQL과 유사합니다 여러 측면에서. 블록 구조화되고 명령적인 언어입니다 (모든 변수는 선언되어야합니다). PL/SQL에는 더 많은 것이 있습니다 그것보다 특징PostgreSQL대응하지만토토 핫/pgsql허용 많은 기능을 위해 개선되고 있습니다. 끊임없이.

19.11.1. 주요 차이점

Oracle에서 포팅 할 때 명심해야 할 사항 에게PostgreSQL:

  • 기본 매개 변수 없음PostgreSQL.

  • 당신은 함수를 과부하 할 수 있습니다PostgreSQL. 이것은 종종 작동하는 데 사용됩니다 기본 매개 변수가 부족합니다.

  • 과제, 루프 및 조건부는 비슷합니다.

  • 커서가 필요 없음postgresql, 쿼리를 문장 (아래 예제 참조)

  • inPostgreSQLYou필요탈출 단일 따옴표. 보다섹션 19.11.1.1.

19.11.1.1. 그것을 인용하십시오 : 싱글을 탈출하십시오 인용 부호

inPostgreSQL당신은 필요합니다 기능 정의 내부에서 단일 따옴표를 피하십시오. 이것 때때로, 특히 당신이 다른 함수를 생성하는 함수를 생성하고 있습니다 안에예제 19-6. 많은 것을 피할 때 명심해야 할 한 가지 단일 따옴표는 시작/끝을 제외하고는입니다 인용문, 다른 모든 사람들은 수량으로도 올 것입니다.

테이블 19-1특종을 제공합니다. (당신은이 작은 것을 사랑할 것입니다 차트.)

표 19-1. 단일 따옴표 도피 차트

아니오. 인용문 usage exam토토 핫e 결과
1 기능 본체를 시작/종료하려면
함수 만들기 foo ()는 정수를 '...'로 반환합니다.
언어 '토토 핫pgsql';
as
2 과제에서 문의를 선택하고, 구분합니다 문자열 등
a_output : = ''blah '';
f_name = ''foobar ''; 사용자 중에서 *를 선택하십시오.
선택 * 사용자에서 선택하십시오 f_name = 'foobar';
4 결과에 두 개의 단일 따옴표가 필요할 때 그 문자열을 종료하지 않고 문자열.
a_output : = a_output || ''그리고 이름 
    ``foobar '' 'and ...' '와 같은
그리고 'foobar'와 같은 이름 및 ...
6 결과에서 이중 인용문을 원할 때 끈and해당 문자열 종료.
a_output : = a_output || ''그리고 이름 
    ``foobar '' '' '
그리고 이름과 같은 이름 'foobar'
10 결과에서 두 개의 단일 따옴표를 원할 때 문자열 (8 인용문을 설명하는)and그것을 종료하십시오 문자열 (2). 당신은 아마도 그것을 필요로 할 것입니다 다른 기능을 생성하기 위해 함수를 사용하고있었습니다 (in예 19-6).
a_output : = a_output || ''v_ ''|| 
    referrer_keys.kind || '' 좋다 '''''''''' 
    || referrer_keys.key_string || '' '' '' '' '' '' ' 
    그런 다음`` '' '' '||를 반환하십시오 referrer_keys.referrer_type 
    || '' '' '';; 끝 If; '';
if v _ <... 좋아요 ``<... ''그런 다음``<... ''; 끝 만약에;

19.11.2. 포팅 기능

예 19-5. 간단한 기능

여기 오라클 기능이 있습니다 :

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

이 기능을 살펴보고의 차이점을 보자.토토 핫/pgsql:

  • PostgreSQL그렇지 않습니다 매개 변수 이름이 지정되었습니다. 당신은 그들을 명시 적으로 별명해야합니다 당신의 기능 내부.

  • Oracle은 가질 수 있습니다in, outinout매개 변수가 함수로 전달되었습니다. 그만큼inout18565_18668PostgreSQL"in"매개 변수 및 함수 단일 값 만 반환 할 수 있습니다.

  • thereturn키워드 함수 프로토 타입 (기능 본문이 아님)이됩니다반환inPostgreSQL.

  • onPostgreSQL함수는 단일 따옴표를 구분 제작자로 사용하여 생성됩니다. 그래서 당신은 당신의 기능 내에서 단일 따옴표를 피해야합니다. (때때로 꽤 성가시킬 수 있습니다. 참조섹션 19.11.1.1).

  • the/표시 오류명령 존재하지 않음PostgreSQL.

그래서 포팅 될 때이 함수가 어떻게 보이는지 봅시다PostgreSQL:

함수 생성 또는 교체 CS_FMT_BROWSER_VERSION (Varchar, Varchar)
varchar를 '로 반환합니다.
선언하다
    v_name 별칭 $ 1;
    $ 2에 대한 v_version 별칭;
시작하다
    v_version이 null이면 그렇다면
        반환 v_name;
    끝 IF;
    반환 v_name || ''/''|| v_version;
끝;
'언어'plpgsql ';

예 19-6. 다른 기능을 생성하는 함수 기능

다음 절차는 a에서 행을 잡습니다.select진술 및 큰 기능을 구축합니다 결과와 함께if진술, 효율성을 위해. 특히 주목하십시오 커서의 차이,for루프, 그리고 단일 따옴표를 피해야 할 필요성PostgreSQL.

절차 작성 또는 교체 CS_UPDATE_REFERRER_TYPE_PROC IS
    Cursor referrer_keys입니다 
        CS_REFERRER_KEYS에서 *를 선택하십시오 
        try_order의 주문;

    a_output varchar (4000); 
시작하다 
    A_OUTPUT : = '기능 작성 또는 교체 CS_FIND_REFERRER_TYPE (VARCHOR의 V_HOST, VARCHAR, VARCHAR, VADDOMAIN 
Varchar의 v_url) 반환 바르 차르가 시작됩니다. '; 

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

    a_output : = a_output || '귀환 널; 끝;'; 
    즉각적인 a_output를 실행합니다. 
끝; 
/ 
오류 표시

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

함수 만들기 CS_UPDATE_REFERRER_TYPE_PROC () 정수를 반환합니다.
선언하다
    참조 _keys 레코드;  - a에 사용할 일반 레코드를 선언하십시오.
    a_output varchar (4000);
시작하다 
    a_output : = ''기능 생성 CS_FIND_REFERRER_TYPE (Varchar, Varchar, Varchar) 
                  varchar를`` '' '로 반환합니다. 
                     선언하다 
                         $ 1의 V_host 별칭; 
                         V_Domain 별칭 $ 2; 
                         3 달러에 대한 v_url 별칭;
                     시작하다 ''; 

    - 
    - 루프 용 쿼리 결과를 스캔하는 방법에 주목하십시오.
    - for <crecor 구성을 사용합니다.
    -

    select * in select * from cs_referrer_keys writ_order loop의 referrer_keys 용.
        a_output : = a_output || ''v_ ''|| referrer_keys.kind || '' 좋다 '''''''''' 
                 || referrer_keys.key_string || `` '' '' '' '' ''그런 다음‘ '' '' ' 
                 || referrer_keys.referrer_type || '' '' '';; 끝 If; ''; 
    엔드 루프; 

    a_output : = a_output || ``return null; 끝; '' ''언어 '' 'PLPGSQL' '' ';' '; 

    - 변수를 대체하지 않기 때문에 작동합니다.
    - 그렇지 않으면 실패합니다. 기능을 실행하는 다른 방법으로 수행하십시오

    a_output를 실행하십시오. 
끝; 
'언어'plpgsql ';

예 19-7. 문자열이 많은 절차 조작 및 아웃 매개 변수

다음 Oracle PL/SQL 절차는 구문 분석에 사용됩니다. URL 및 여러 요소 (호스트, 경로 및 쿼리)를 반환합니다. 그것은 이후 절차토토 핫/pgsql함수는 하나의 값만이 될 수 있습니다 반품 (참조섹션 19.11.3). 안에PostgreSQL, 이것을 해결하는 한 가지 방법은 절차를 세 가지 다른 기능 : 하나는 호스트를 반환하고 다른 하나를 반환합니다 경로와 쿼리의 경우.

절차 작성 또는 교체 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, '//'); -postgresql기기 기능이 없습니다

    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);
끝;
/
오류 표시;

이 절차가 어떻게 번역 될 수 있는지PostgreSQL:

기능 작성 또는 교체 CS_PARSE_URL_HOST (VARCHAR) VARCHARS를 반환합니다. 
선언하다 
    $ 1의 V_URL 별칭; 
    v_host varchar; 
    v_path varchar; 
    A_POS1 정수; 
    A_POS2 정수; 
    A_POS3 정수; 
시작하다 
    v_host : = 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 : = ''/''; 
        반환 v_host; 
    끝 IF; 

    v_host : = substr (v_url, a_pos1 + 2, a_pos2 -a_pos1-2); 
    반환 v_host; 
끝; 
'언어'plpgsql ';

참고 : PostgreSQLinstr함수이므로 조합을 사용하여 작업을 수행 할 수 있습니다. 다른 기능. 나는 이것을하는 것에 지쳤고 나의 것을 창조했다 소유하다instr함수 Oracle과 똑같이 행동하십시오 (인생이 더 쉬워집니다). 보다 그만큼섹션 19.11.6코드의 경우

19.11.3. 절차

Oracle 절차는 약간 더 유연성을 제공합니다 명시 적으로 반환 할 필요가 없기 때문에 개발자 사용을 통해 가능합니다.inout또는out매개 변수.

예 :

절차 작성 또는 교체 CS_CREATE_JOB (v_JOB_ID Integer)는 IS입니다
    a_running_job_count 정수;
    Pragma Autonomous_transaction;(1)시작
    독점 모드의 잠금 테이블 CS_JOBS;(2)a_running_job_count로 count (*)를 선택하십시오 
    CS_JOBS에서
    여기서 end_stamp는 null;

    a_running_job_count 0 인 경우
        저지르다; - 무료 잠금(3)REASE_APPLICATION_ERROR (-20000, '새 작업을 만들 수 없습니다 : 현재 작업이 실행 중입니다.');
    끝 IF;

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

    시작하다
        cs_jobs (job_id, start_stamp) 값 (v_job_id, sysdate)에 삽입;
        DUP_VAL_ON_INDEX가 NULL으로 예외; - 이미 존재하는지 걱정하지 마십시오(4)끝;
    저지르다;
끝;
/
오류 표시

이와 같은 절차는 쉽게 변환 될 수 있습니다PostgreSQL반환 기능Integer. 이 절차는 특히 우리에게 몇 가지를 가르쳐 줄 수 있기 때문에 흥미 롭습니다 :

(1)
없음Pragma진술 안에PostgreSQL.
(2)
당신이 할 경우잠금 테이블in토토 핫/pgsql, 잠금 장치 호출 트랜잭션이 될 때까지 해제되지 않습니다 완성된.
(3)
당신은 또한 거래를 할 수 없습니다토토 핫/pgsql절차. 전체 기능 (및 그에서 호출 된 다른 기능)은 다음과 같습니다 거래에서 실행 및PostgreSQL결과를 롤백합니다 뭔가 잘못 됐어. 그러므로 단 하나시작명령문이 허용됩니다.
(4)
예외는 A로 대체해야합니다if진술.

그래서 우리 가이 절차를 포트 할 수있는 방법 중 하나를 봅시다PL/PGSQL:

함수 작성 또는 교체 CS_CREATE_JOB (Integer) 정수를 반환합니다.
선언하다
    $ 1에 대한 v_job_id 별칭;
    a_running_job_count 정수;
    a_num 정수;
    -Pragma Autonomous_transaction;
시작하다
    독점 모드에서 잠금 테이블 CS_JOBS;
    a_running_job_count로 count (*)를 선택하십시오 
    CS_JOBS에서 
    여기서 end_stamp는 null;

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

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

    a_num으로 count (*)를 선택하십시오 
    CS_JOBS에서 
    여기서 job_id = v_job_id;
    찾을 수없는 경우 - 마지막 쿼리에 아무것도 반환되지 않은 경우
        -이 작업은 테이블에 있지 않으므로 삽입하십시오.
        cs_jobs (job_id, start_stamp) 값 (v_job_id, sysdate ())에 삽입;
        반환 1;
    또 다른
        ``일자리가 이미 실행되는 일 ''; 통지를 제기하십시오.(1)종료 if;

    반환 0;
끝;
'언어'plpgsql ';
(1)
in in in에 대한 통지 (또는 오류)를 제기 할 수있는 방법에 주목하십시오.토토 핫/pgsql.

19.11.4. 패키지

참고 :나는 패키지를 직접 많이하지 않았다. 그러니 여기에 실수가 있으면 알려주세요.

패키지는 Oracle이 PL/SQL을 캡슐화하도록 제공하는 방법입니다. Java 클래스와 같은 한 엔티티로의 진술과 기능 방법과 객체를 정의하는 곳. 당신은 이것에 액세스 할 수 있습니다 a와 객체/방법"."(점). 다음은 오라클의 예입니다 ACS 4의 패키지 (Arsdigita 커뮤니티 시스템) :

패키지 바디 AC를 만들거나 교체하십시오
처럼
  함수 add_user (
    user_id user.user_id%유형 기본 널,
    ACS_OBJECTS.OBJECT_TYPE%유형 기본 '사용자', Object_Type,
    acs_objects.creation_date%유형 기본 sysdate의 creation_date,
    acs_objects.creation_user%유형 기본 널, creation_user
    acs_objects.creation_ip%유형 기본 널, creation_ip,
  ...
  ) user.user_id%유형을 반환합니다
  이다
    v_user_id users.user_id%유형;
    v_rel_id membership_rels.rel_id%유형;
  시작하다
    v_user_id : = acs_user.new (user_id, object_type, creation_date,
                creation_user, creation_ip, 이메일, ...
    반환 v_user_id;
  끝;
끝 AC;
/
오류 표시

우리는 이것을 포트로PostgreSQLOracle 패키지의 다른 객체를 표준 명명 규칙과 기능합니다. 우리는 지불해야합니다 기본값 부족과 같은 다른 세부 사항에 대한 관심 매개 변수PostgreSQL함수. 위의 패키지는 같은 것이 될 것입니다 이것:

함수 생성 ACS__ADD_USER (정수, 정수, 바르 차, 타임 스탬프, 정수, 정수, ...)
정수를 '로 반환합니다.
선언하다
    user_id alias $ 1;
    대상 _type 별칭 $ 2;
    $ 3에 대한 Creation_date 별칭;
    Creation_user 별칭 $ 4;
    5 달러에 대한 Creation_ip 별칭;
    ...
    v_user_id users.user_id%유형;
    v_rel_id membership_rels.rel_id%유형;
시작하다
    v_user_id : = acs_user__new (user_id, object_type, creation_date, creation_user, creation_ip, ...);
    ...

    반환 v_user_id;
끝;
'언어'plpgsql ';

19.11.5. 볼 다른 것들 을 위한

19.11.5.1. 실행하다

thePostgreSQL버전execute잘 작동하지만 당신은 가지고 있습니다 사용하는 것을 기억하려면quote_literal (텍스트)andquote_string (텍스트)설명대로섹션 19.5.4. 유형의 구성execute ''select * from $ 1 '';작동하지 않습니다 이 기능을 사용하지 않는 한.

19.11.5.2. 최적화토토 핫/pgsql기능

PostgreSQL두 가지를 제공합니다 실행 최적화를위한 기능 생성 수정 자 :iscachable(함수는 항상 동일하게 반환합니다 동일한 논증이 주어지면 결과) 및isstrict(함수가 있으면 NULL을 반환합니다 인수는 null). 상담생성 기능자세한 내용 참조.

이러한 최적화 속성을 사용하려면 사용with당신의 수정 자기능 만들기진술. 무엇 좋다:

함수 만들기 foo (...)는 정수를 반환합니다.
...
'언어'plpgsql '
(isstrict, iscachable);

19.11.6. 충수

19.11.6.1. 내 코드instr기능

-
- Oracle의 상대를 모방하는 기기 기능
- 구문 : inst (String1, String2, [n], [m]) 여기서 []는 선택적 매개 변수를 나타냅니다.
- 
- mth의 nth 캐릭터에서 시작하는 string1을 검색합니다.
- String2의 발생. n이 음수이면 뒤로 검색하십시오. M이라면
- 통과하지 말고 1이라고 가정합니다 (첫 번째 문자에서 검색이 시작됩니다).
-
- Roberto Mello (rmello@fslc.usu.edu)
- Robert Gaszewski (graszew@poland.com)에 의해 수정되었습니다.
-GPL V2 이상에 따라 라이센스가 부여됩니다.
-

기능 기기 생성 (Varchar, Varchar)은 정수를 '로 반환합니다.
선언하다
    POS 정수;
시작하다
    POS : = 기기 ($ 1, $ 2,1);
    POS 리턴;
끝;
'언어'plpgsql ';

기능 기기 생성 (Varchar, Varchar, Integer)은 정수를 '로 반환합니다.
선언하다
    $ 1의 문자열 별칭;
    String_to_search alias $ 2;
    Beg_index 별칭 $ 3;
    POS 정수 NOL NULL DEFAULT 0;
    temp_str varchar;
    정수를 구걸하십시오.
    길이 정수;
    ss_length 정수;
시작하다
    beg_index 0이면

       temp_str : = substring (beg_index의 문자열);
       pos : = 위치 (temp_str의 String_to_search);

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

       beg 0 루프
           temp_str : = 서브 스트링 (ss_length의 beg에서 문자열);
                 pos : = 위치 (temp_str의 String_to_search);

                 POS 0이라면
                           반환 구걸;
                 끝 IF;

                 Beg : = Beg -1;
       엔드 루프;
       반환 0;
    끝 IF;
끝;
'언어'plpgsql ';

-
- Robert Gaszewski (graszew@poland.com) 작성
-GPL V2 이상에 따라 라이센스가 부여됩니다.
-
기능 악기 생성 (Varchar, Varchar, Integer, Integer)은 정수를 다시 반환합니다.
선언하다
    $ 1의 문자열 별칭;
    String_to_search alias $ 2;
    Beg_index 별칭 $ 3;
    4 달러에 대한 alse_index 별칭;
    POS 정수 NOL NULL DEFAULT 0;
    alkes_number 정수 NOL NULL DEFAULT 0;
    temp_str varchar;
    정수를 구걸하십시오.
    나는 정수;
    길이 정수;
    ss_length 정수;
시작하다
    beg_index 0이면
        beg : = beg_index;
        temp_str : = substring (beg_index의 문자열);

        1. Occur_index 루프
            pos : = 위치 (temp_str의 String_to_search);

            I = 1이면
                beg : = beg + pos -1;
            또 다른
                beg : = beg + pos;
            끝 IF;

            temp_str : = 서브 스트링 (beg + 1의 문자열);
        엔드 루프;

        POS = 0이면
            반환 0;
        또 다른
            반환 구걸;
        끝 IF;
    또 다른
        ss_length : = char_length (String_to_search);
        길이 : = char_length (문자열);
        beg : = 길이 + beg_index -ss_length + 2;

        beg 0 루프
            temp_str : = 서브 스트링 (ss_length의 beg에서 문자열);
            pos : = 위치 (temp_str의 String_to_search);

            POS 0이라면
                alkes_number : = alkes_number + 1;

                alke_number = cose_index가있는 경우
                    반환 구걸;
                끝 IF;
            끝 IF;

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

        반환 0;
    끝 IF;
끝;
'언어'plpgsql ';