이 섹션은 간의 차이점을 설명합니다.postgresql's토토 핫/pgsql언어 및 Oracle 's토토 핫/sql언어 의 응용 프로그램Oracle® toPostgreSQL.
토토 핫/pgsqlPL/SQL과 유사합니다 여러 측면에서. 블록 구조화되고 명령적인 언어이며 그리고 모든 변수는 선언되어야합니다. 과제, 루프, 조건부는 비슷합니다. 당신이 유지 해야하는 주요 차이점 에서 포팅 할 때 마음토토 핫/sqlto토토 핫/pgsqlare :
매개 변수에 대한 기본값은 없습니다PostgreSQL.
당신은에서 함수 이름을 과부하 할 수 있습니다.PostgreSQL. 이것은 종종 작동하는 데 사용됩니다 기본 매개 변수가 부족합니다.
SQL 명령에 사용 된 이름이 열인 경우 테이블 이름 또는 함수 변수에 대한 참조PL/SQL열로 취급합니다 이름, while토토 핫/pgsql취급 변수 이름입니다. 그러한 모호성을 피하는 것이 가장 좋습니다 첫 번째는하지만 필요한 경우 다음으로 고칠 수 있습니다. 모호한 이름을 올바르게 예약합니다. (보다섹션 38.10.1.)
커서가 필요 없음토토 핫/pgsqlfor진술. (보다예제 38-6.)
inPostgreSQL기능 본문은 문자열 문자로 작성해야합니다. 그러므로 달러 인용문을 사용하거나 단일 따옴표를 피해야합니다. 기능 본체. (보다섹션 38.11.1.)
패키지 대신 스키마를 사용하여 구성하십시오 그룹으로의 기능.
패키지가 없으므로 패키지 레벨이 없습니다 변수. 이것은 다소 성가시다. 당신은 유지할 수 있습니다 대신 임시 테이블의 세션 당 상태.
정수for루프Reverse다르게 작업 :PL/SQL두 번째에서 카운트 하락합니다 첫 번째 숫자,PL/PGSQL첫 번째에서 카운트 다운 루프 경계를 바꾸어야하는 두 번째 숫자 포팅 할 때. 이 비 호환성은 불행하지만 그렇습니다 변경되지 않을 것입니다. (보다섹션 38.6.3.5.)
예제 38-5간단한 기능을 포트하는 방법을 보여줍니다PL/SQLto토토 핫/pgsql.
예 38-5. 에서 간단한 기능 포팅PL/SQLto토토 핫/pgsql
여기가 있습니다Oracle 토토 핫/sql기능 :
함수 작성 또는 교체 CS_FMT_BROWSER_VERSION (V_NAME VARCHAR, v_version varchar) 반환 바르 르 차입니다 시작하다 v_version이 null이면 그렇다면 반환 v_name; 끝 IF; 반환 v_name || '/'|| v_version; 끝; / 오류 표시;
이 기능을 살펴보고 차이점을 보자 에 비해토토 핫/pgsql:
thereturn키워드 함수 프로토 타입 (기능 본문이 아님)이됩니다반환inpostgresql. 또한,isas, 그리고 당신은 a를 추가해야합니다.언어절로토토 핫/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;
예제 38-6다른 기능을 생성하는 함수를 포트하는 방법을 보여줍니다 기능 및 다음 인용 문제를 처리하는 방법.
예 38-6. 생성하는 함수를 포팅합니다 의 또 다른 함수토토 핫/sqlto토토 핫/pgsql
다음 절차는 a에서 행을 잡습니다.select명령문과 큰 기능을 구축합니다 결과와 함께if진술, 효율성을 위해. 특히 주목하십시오 커서와의 차이점for루프.
이것은 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 varchar, Varchar의 V_Domain, Varchar의 V_URL) Return varchar가 시작됩니다. '; 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 () voids는 $ func $로 void을 반환합니다 선언하다 참조 _key 레코드; - a에 사용할 일반 레코드를 선언하십시오. func_body 텍스트; func_cmd 텍스트; 시작하다 func_body : = '시작'; - 루프 용 쿼리 결과를 스캔하는 방법에 주목하십시오. - for <crecor 구성을 사용합니다. 선택 *에서 cs_referrer_keys wrome에서 referrer_key의 경우 try_order loop의 주문 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_LITERALTO 인용 표시가 두 배로 늘어납니다. 이 기술이 필요합니다 우리는 정의를 위해 달러 인용문을 안전하게 사용할 수 없기 때문에 새로운 기능 : 우리는 어떤 줄이 될지 확실하지 않습니다. 에서 보간referrer_key.key_string필드. (우리는 여기서referrer_key.kind항상 신뢰할 수 있습니다 BE호스트, 도메인또는url그러나referrer_key.key_string무엇이든, 특히 그것은 달러 표지판을 포함 할 수 있습니다.) 이것 기능은 실제로 Oracle Original의 개선입니다. 이 깨진 코드를 생성하지 않기 때문에referrer_key.key_string또는referrer_key.referrer_type견적을 포함하십시오 점수.
예제
38-7|out매개 변수 및 문자열 조작.PostgreSQLa
내장instr
기능이지만
다른 기능의 조합을 사용하여 하나를 만들 수 있습니다.in섹션
38.12.3a토토 핫/pgsql구현instr
포팅에 사용할 수 있습니다
더 쉬운.
예 38-7. 문자열로 절차를 포팅합니다 조작 및Out매개 변수PL/SQLto토토 핫/pgsql
다음OraclePL/SQL 절차는 URL을 구문 분석하고 여러 반환하는 데 사용됩니다. 요소 (호스트, 경로 및 쿼리).
이것은 Oracle 버전입니다 :
절차 작성 또는 교체 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); 끝; / 오류 표시;
여기에 가능한 번역이 있습니다PL/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;
이 기능은 다음과 같이 사용할 수 있습니다.
선택 *에서 CS_PARSE_URL ( 'http://foobar.com/query.cgi?baz');
예제 38-8다수를 사용하는 절차를 포트하는 방법을 보여줍니다 Oracle에 특화된 기능.
예 38-8. 절차 포팅PL/SQLtoPL/PGSQL
Oracle 버전 :
절차 작성 또는 교체 CS_CREATE_JOB (v_job_id)는 IS입니다 a_running_job_count 정수; Pragma Autonomous_transaction;(1)시작 독점 모드의 잠금 테이블 CS_JOBS;(2)cs_jobs에서 a_running_job_count로 count (*)를 선택하여 end_stamp가 null; a_running_job_count 0 인 경우 저지르다; - 무료 잠금(3)rase_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; - 이미 존재하는지 걱정하지 마십시오 끝; 저지르다; 끝; / 오류 표시
이와 같은 절차는 쉽게 변환 할 수 있습니다PostgreSQL함수 반환void. 이 절차는 특히 우리에게 일부를 가르쳐 줄 수 있기 때문에 특히 흥미 롭습니다 것들:
이것은 우리 가이 절차를 포트 할 수있는 방법입니다토토 핫/pgsql:
함수 생성 또는 교체 CS_CREATE_JOB (v_JOB_ID 정수)는 void를 $$로 반환합니다. 선언하다 a_running_job_count 정수; 시작하다 독점 모드에서 잠금 테이블 CS_JOBS; end_stamp가 null 인 cs_jobs에서 a_running_job_count로 count (*)를 선택하십시오. a_running_job_count 0 인 경우 예외 제외 '새 작업을 만들 수 없음 : 현재 작업이 실행 중입니다';(1)END 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;
이 섹션은 언제 볼 수있는 몇 가지 다른 사항을 설명합니다. 포팅 오라클PL/SQL함수PostgreSQL.
in토토 핫/pgsql, 언제 예외는에 의해 잡혔다.예외조항, 블록 이후 모든 데이터베이스 변경시작자동으로 롤백됩니다. 즉, 행동은 오라클에서 얻을 수있는 것과 같습니다. 와 함께:
시작 SavePoint S1; ... 여기 코드 ... 예외 언제 ... 그럼 S1 롤백; ... 여기 코드 ... 언제 ... 그럼 S1 롤백; ... 여기 코드 ... 끝;
사용하는 Oracle 절차를 번역하는 경우SavePoint및롤백으로이 스타일에서는 작업이 쉽습니다. 그냥 생략SavePointand롤백으로. 절차가있는 경우 사용SavePoint및롤백으로다른 방식으로 일부 실제 생각이 필요합니다.
the토토 핫/pgsql버전execute토토 핫/sql버전이지만 있습니다
사용하는 것을 기억하려면quote_literal
andQUOTE_INDEN
설명대로섹션
38.5.4. 유형의 구성execute 'select * from $ 1';작동하지 않습니다
이러한 기능을 사용하지 않는 한 안정적으로.
PostgreSQL두 가지를 제공합니다 실행 최적화를위한 기능 생성 수정 자 :"변동성"(함수 여부 동일한 인수가 주어지면 항상 같은 결과를 반환합니다) 그리고"엄격함"( 인수가 null이면 함수를 반환합니다). 상담PostgreSQL :자세한 내용 참조 페이지.
이러한 최적화 속성을 사용할 때함수 만들기진술이 보일 수 있습니다 다음과 같은 것 :
함수 생성 foo (...)는 정수를 $$로 반환합니다 ... $$ 언어 plpgsql 엄격한 불변성;
이 섹션에는 세트에 대한 코드가 포함되어 있습니다
오라클 호환instr
함수
포팅 노력을 단순화하는 데 사용할 수 있습니다.
- - Oracle의 상대를 모방하는 기기 기능 - 구문 : inst (String1, String2, [n], [m])는 []가 선택적 매개 변수를 나타냅니다. - -Mth 발생을 위해 Nth 캐릭터에서 시작하여 String1을 검색합니다. - String2. n이 음수이면 뒤로 검색하십시오. M이 통과되지 않으면 - 1이라고 가정합니다 (첫 번째 문자에서 검색이 시작됩니다). - 기능 악기 (Varchar, Varchar)를 작성하십시오. 정수를 $$로 반환합니다 선언하다 POS 정수; 시작하다 POS : = 기기 ($ 1, $ 2, 1); POS 리턴; 끝; $$ 언어 plpgsql 엄격한 불변; 기능 악기 만들기 (String varchar, String_to_search 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); 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 엄격한 불변; 기능 악기 생성 (String varchar, String_to_search Varchar, beg_index 정수, cose_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 엄격한 불변성;