Postgresql 9.3.25 문서화 | ||||
---|---|---|---|---|
이전 | Postgre메이저 토토 사이트 : 문서 : 9.3 : PL/PG메이저 토토 사이트 -메이저 토토 사이트 절차 언어 | 40 장윈 토토/pgsql - SQL절차 언어 | 다음 |
이 섹션은 간의 차이점을 설명합니다.postgresql's윈 토토/pgsql언어와 Oracle 's윈 토토/sql언어 의 응용 프로그램Oracle® toPostgreSQL.
윈 토토/pgsqlPL/SQL과 유사합니다 여러 측면에서. 블록 구조화되고 명령적인 언어이며 모든 변수는 선언해야합니다. 과제, 루프, 조건부 비슷합니다. 당신이 할 때 명심해야 할 주요 차이점 에서 포팅윈 토토/sqlto윈 토토/pgsqlare :
SQL 명령에 사용 된 이름이 열 이름이 될 수있는 경우 테이블 또는 함수 변수에 대한 참조윈 토토/sql열 이름으로 취급합니다. 이것 에 해당합니다.윈 토토/pgsql's윈 토토pgsql.variable_conflict=use_column행동, 기본값이 아닙니다 설명섹션 40.10.1. 첫 번째 모호성을 피하는 것이 가장 좋습니다. 장소,하지만 의존하는 많은 양의 코드를 포트 해야하는 경우 이 행동에 대해 설정variable_conflict최상의 솔루션 일 수 있습니다.
inPostgreSQL기능 본문 문자열 문자로 작성해야합니다. 따라서 사용해야합니다 기능 본문에서 달러 인용 또는 탈출. (보다섹션 40.11.1.)
패키지 대신 Schemas를 사용하여 기능을 구성하십시오. 여러 떼.
패키지가 없으므로 패키지 레벨이 없습니다 변수. 이것은 다소 성가시다. 당신은 유지할 수 있습니다 대신 임시 테이블의 세션 당 상태.
Integerfor루프Reverse다르게 작업 :윈 토토/sql두 번째 숫자에서 카운트 다운 첫 번째, 동안윈 토토/pgsql카운트 첫 번째 숫자에서 두 번째 숫자로 줄이면 루프 바운드가 필요합니다. 포팅 할 때 교체해야합니다. 이 비 호환성은 불행하지만 변경되지 않을 것입니다. (보다섹션 40.6.3.5.)
for쿼리 위의 루프 (이외의 커서)도 다르게 작동합니다 : 대상 변수에는 있어야합니다 ,윈 토토/sql항상 암시 적으로 선언합니다. 이것의 장점은 루프 종료 후에 가변 값은 여전히 액세스 할 수 있습니다.
커서 사용에 대한 다양한 표기차가 있습니다. 변수.
예제 40-8간단한 기능을 포트하는 방법을 보여줍니다윈 토토/sqlto윈 토토/pgsql.
예 40-8. 에서 간단한 기능 포팅PL/SQLto윈 토토/pgsql
여기에Oracle PL/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언어절로윈 토토/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;
예제 40-9다른 함수를 생성하는 함수를 포트하는 방법을 보여줍니다. 그리고 계속해서 인용하는 인용 문제를 처리하는 방법.
예 40-9. 다른 기능을 생성하는 함수를 포팅합니다 의 함수윈 토토/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 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을 반환합니다 선언하다 참조 _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_string무엇이든, 특히 그것은 달러 표지판을 포함 할 수 있습니다.) 이것 기능은 실제로 Oracle Original의 개선입니다. 이 깨진 코드를 생성하지 않습니다.referrer_key.key_string또는referrer_key.referrer_type견적을 포함하십시오 점수.
예
40-10|out매개 변수 및 문자열 조작.PostgreSQL내장이 없습니다inst
함수이지만 만들 수 있습니다
하나는 다른 기능의 조합을 사용합니다. 안에섹션 40.12.3A가 있습니다PL/PGSQL구현
의instr
당신은 만들 수 있습니다
당신의 포팅이 쉬워요.
예 40-10. 문자열 조작으로 절차를 포팅합니다 그리고out매개 변수윈 토토/sqlto윈 토토/pgsql
다음Oracle윈 토토/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); 끝; / 오류 표시;
여기에 가능한 번역이 있습니다윈 토토/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');
예제 40-11수많은 기능을 사용하는 절차를 포트하는 방법을 보여줍니다. 오라클에만 해당됩니다.
예 40-11. 절차 포팅PL/SQLtoPL/PGSQL
Oracle 버전 :
절차 작성 또는 교체 CS_CREATE_JOB (v_JOB_ID Integer)는 IS입니다 a_running_job_count 정수; Pragma Autonomous_transaction;(1)시작 독점 모드의 잠금 테이블 CS_JOBS;(2)cs_jobs에서 a_running_job_count로 count (*)를 선택하십시오. a_running_job_count 0 인 경우 저지르다; - 무료 잠금(3)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, 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)종료 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;이 절차와 Oracle Evalent는 독점적 인 잠금이입니다.CS_JOBS테이블은 전화 할 때까지 개최됩니다 거래가 완료됩니다. 또한 발신자가 나중에 중단되는 경우 (for 예제 오류로 인해이 절차의 효과는 다음과 같습니다. 롤백.
이 섹션은 언제 볼 수있는 몇 가지 다른 사항을 설명합니다. 포팅 오라클윈 토토/sql기능PostgreSQL.
in윈 토토/pgsql, 예외 일 때 에 의해 잡힌다예외조항, 모두 블록 이후 데이터베이스 변경시작자동으로 롤백됩니다. 즉, 행동은 동일합니다 오라클에서 얻을 수있는 것 :
시작 SavePoint S1; ... 여기 코드 ... 예외 언제 ... 그럼 S1 롤백; ... 여기 코드 ... 언제 ... 그럼 S1 롤백; ... 여기 코드 ... 끝;
사용하는 Oracle 절차를 번역하는 경우SavePoint및롤백으로이 스타일에서는 작업이 쉽습니다.SavePointand롤백으로. 사용하는 절차가있는 경우SavePoint및롤백으로다른 방식으로 실제 생각이 필요합니다.
the윈 토토/pgsql버전execute와 유사하게 작동합니다PL/SQL버전이지만해야합니다
사용하는 것을 잊지 마십시오QUOTE_LITERAL
andQUOTE_INDEN
설명대로섹션
40.5.4. 유형의 구성실행
'선택 * $ 1';사용하지 않는 한 안정적으로 작동하지 않습니다
이 기능.
PostgreSQL두 가지를 제공합니다 실행 최적화를위한 기능 생성 수정 자 :"변동성"(함수가 항상 반환되는지 여부 동일한 인수가 주어지면 동일한 결과) 및"엄격함"(함수가 if를 반환하는지 여부 모든 주장은 null입니다). 상담함수 만들기참조 페이지 세부.
이러한 최적화 속성을 사용할 때함수 생성명령문이 보일 수 있습니다 다음과 같은 것 :
함수 생성 foo (...)는 정수를 $$로 반환합니다 ... $$ 언어 plpgsql 엄격한 불변성;
이 섹션은 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 엄격한 불변성;