이 섹션에서는 다음과 같은 차이점을 설명합니다.포스트그레SQL's스포츠 토토/pgSQL언어와 오라클의PL/SQL언어, 포팅하는 개발자를 돕기 위해 의 지원서오라클® ~PostgreSQL.
스포츠 토토/pgSQLPL/SQL과 유사합니다. 여러 측면에서. 블록 구조의 명령형 언어입니다. 그리고 모든 변수는 선언되어야 합니다. 할당, 루프, 조건문도 비슷합니다. 유지해야 할 주요 차이점 이동할 때 주의하세요.PL/SQL에스포츠 토토/pgSQL다음은:
다음에는 매개변수에 대한 기본값이 없습니다.PostgreSQL.
함수 이름을 오버로드할 수 있습니다.포스트그레SQL. 이것은 종종 작업에 사용됩니다. 기본 매개변수가 부족합니다.
커서가 필요하지 않습니다.스포츠 토토/pgSQL, 쿼리를에 입력하세요.for성명. (참조예 35-6.)
에포스트그레SQL당신은 다음을 수행해야 합니다 함수에서 달러 인용을 사용하거나 작은따옴표를 이스케이프하세요. 몸. 참조섹션 35.2.1.
패키지 대신에 스키마를 사용하여 그룹으로 기능합니다.
패키지가 없으므로 패키지 수준이 없습니다. 변수든. 이것은 다소 성가신 일입니다. 당신은 할 수 있습니다 대신 임시 테이블에 세션별 상태를 유지합니다.
예 35-5다음에서 간단한 함수를 이식하는 방법을 보여줍니다.PL/SQL에스포츠 토토/pgSQL.
예 35-5. 다음에서 간단한 함수 포팅하기PL/SQL에스포츠 토토/pgSQL
여기에 있습니다오라클 PL/SQL기능:
함수 생성 또는 교체 cs_fmt_browser_version(v_name IN varchar,
v_version IN varchar)
반환 varchar IS
시작
v_version이 NULL인 경우
RETURN v_name;
종료하면;
RETURN v_name || '/' || v_version;
끝;
/
오류 표시;
이 기능을 살펴보고 차이점을 살펴보겠습니다.스포츠 토토/pgSQL:
오라클가질 수 있습니다IN, 밖으로및INOUT함수에 전달된 매개변수.INOUT14572_14675포스트그레SQL만 있음IN매개변수가 있으므로 거기에 매개변수 종류에 대한 사양이 없습니다.
그반환키워드 함수 프로토타입(함수 본문 아님)은 다음과 같습니다.반환inPostgreSQL. 또한,IS되다AS, 그리고 다음을 추가해야 합니다.언어절 왜냐하면스포츠 토토/pgSQL이것이 유일한 함수 언어는 아닙니다.
에PostgreSQL, 함수 본문은 문자열 리터럴로 간주되므로 주위에 따옴표나 달러 따옴표를 사용해야 합니다. 이는 종료를 대체합니다./Oracle 접근 방식에서.
그오류 표시명령은 다음과 같습니다 에는 존재하지 않습니다.포스트그레SQL, 오류가 보고되므로 필요하지 않습니다. 자동으로.
이 기능을 다음으로 이식하면 다음과 같습니다.포스트그레SQL:
함수 생성 또는 교체 cs_fmt_browser_version(v_name varchar,
v_version varchar)
varchar를 $$로 반환합니다.
시작
v_version이 NULL인 경우
RETURN v_name;
종료하면;
RETURN v_name || '/' || v_version;
끝;
$$ 언어 plpgsql;
예 35-6다른 함수를 생성하는 함수를 이식하는 방법을 보여줍니다. 함수 및 그에 따른 인용 문제를 처리하는 방법을 설명합니다.
예 35-6. 생성하는 함수 포팅 다른 기능PL/SQL에스포츠 토토/pgSQL
다음 절차는 a에서 행을 가져옵니다.선택문을 작성하고 큰 함수를 빌드합니다. 결과는 다음과 같습니다.IF문장, 효율성을 위해서. 특히 주목하세요. 커서와의 차이점for루프.
이것은 오라클 버전입니다:
프로시저 생성 또는 교체 cs_update_referrer_type_proc IS
커서 Referrer_keys IS
SELECT * cs_referrer_keys에서
ORDER BY try_order;
func_cmd VARCHAR(4000);
시작
func_cmd := '함수 생성 또는 교체 cs_find_referrer_type(v_host IN VARCHAR,
v_domain IN VARCHAR, v_url IN VARCHAR) RETURN VARCHAR IS BEGIN';
FOR Referrer_key IN Referrer_keys LOOP
func_cmd := func_cmd ||
' IF v_' || Referrer_key.kind
|| '좋아요''' || Referrer_key.key_string
|| ''' 그런 다음 '''를 반환합니다 || Referrer_key.referrer_type
|| '''; 종료 IF;';
엔드 루프;
func_cmd := func_cmd || ' NULL을 반환합니다. 끝;';
즉시 실행 func_cmd;
끝;
/
오류 표시;
이 함수의 결과는 다음과 같습니다포스트그레SQL:
함수 생성 또는 교체 cs_update_referrer_type_proc()는 $func$로 void를 반환합니다.
선언
Referrer_key RECORD; -- FOR에서 사용할 일반 레코드를 선언합니다.
func_body 텍스트;
func_cmd 텍스트;
시작
func_body := '시작' ;
-- FOR 루프에서 쿼리 결과를 검색하는 방법에 주목하세요.
-- FOR <record 구문을 사용합니다.
FOR Referrer_key IN SELECT * FROM cs_referrer_keys ORDER BY try_order LOOP
func_body := func_body ||
' IF v_' || Referrer_key.kind
|| '좋아요' || quote_literal(referrer_key.key_string)
|| ' 그런 다음 반환 ' || quote_literal(referrer_key.referrer_type)
|| '; END IF;' ;
엔드 루프;
func_body := func_body || ' NULL을 반환합니다. 끝;';
func_cmd :=
'함수 생성 또는 교체 cs_find_referrer_type(v_host varchar,
v_domain varchar,
v_url varchar)
varchar AS '를 반환합니다.
|| quote_literal(func_body)
|| ' 언어 plpgsql;' ;
실행 func_cmd;
반품;
끝;
$func$ 언어 plpgsql;
함수 본문이 어떻게 별도로 구성되는지 확인하세요. 그리고 통과했습니다quote_literal에 그 안의 따옴표를 두 배로 늘리세요. 이 기술이 필요합니다 왜냐하면 우리는 정의를 위해 달러 인용을 안전하게 사용할 수 없기 때문입니다. 새 함수: 어떤 문자열이 될지 확실하지 않습니다. 에서 보간됨referrer_key.key_string필드. (우리는 여기서는 다음과 같이 가정합니다.referrer_key.kind항상 신뢰할 수 있습니다 수호스트, 도메인, 또는url하지만referrer_key.key_string아마도 특히 달러 기호가 포함될 수 있습니다.) 기능은 실제로 Oracle 원본을 개선한 것입니다. 왜냐하면 다음과 같은 경우 깨진 코드가 생성되지 않기 때문입니다.referrer_key.key_string또는referrer_key.referrer_type인용문 포함 마크.
예
35-7함수를 포팅하는 방법을 보여줍니다.아웃매개변수 및 문자열 조작.PostgreSQL다음이 없습니다instr기능이 있지만 작업할 수 있습니다.
다른 기능의 조합을 사용하여 주변을 둘러쌉니다.에섹션
35.11.3이 있습니다스포츠 토토/pgSQL구현instr포팅에 사용할 수 있는 것
더 쉬워요.
예 35-7. 문자열을 사용하여 프로시저 이식하기 조작과아웃매개변수:PL/SQL에스포츠 토토/pgSQL
다음오라클PL/SQL 프로시저는 URL을 구문 분석하고 여러 가지를 반환하는 데 사용됩니다. 요소(호스트, 경로 및 쿼리). 에서포스트그레SQL, 함수는 반환만 가능 하나의 값. 이 문제를 해결하는 한 가지 방법은 반환을 수행하는 것입니다. 복합 유형(행 유형)의 값을 지정합니다.
이것은 Oracle 버전입니다:
프로시저 생성 또는 교체 cs_parse_url(
v_url IN VARCHAR,
v_host OUT VARCHAR, -- 다시 전달됩니다.
v_path OUT VARCHAR, -- 이것도 마찬가지입니다.
v_query OUT VARCHAR) -- 그리고 이건
IS
a_pos1 INTEGER;
a_pos2 INTEGER;
시작
v_host := NULL;
v_path := NULL;
v_query := NULL;
a_pos1 := instr(v_url, '//');
만약 a_pos1 = 0이면
반환;
종료하면;
a_pos2 := instr(v_url, '/', a_pos1 + 2);
만약 a_pos2 = 0이면
v_host := substr(v_url, a_pos1 + 2);
v_path := '/';
반환;
종료하면;
v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2);
a_pos1 := instr(v_url, '?', a_pos2 + 1);
만약 a_pos1 = 0이면
v_path := substr(v_url, a_pos2);
반환;
종료하면;
v_path := substr(v_url, a_pos2, a_pos1 - a_pos2);
v_query := substr(v_url, a_pos1 + 1);
끝;
/
오류 표시;
다음에 가능한 번역이 있습니다.스포츠 토토/pgSQL:
CREATE TYPE cs_parse_url_result AS(
v_호스트 VARCHAR,
v_path VARCHAR,
v_query VARCHAR
);
함수 생성 또는 교체 cs_parse_url(v_url VARCHAR)
cs_parse_url_result를 $$로 반환합니다.
선언
입술 cs_parse_url_result;
a_pos1 INTEGER;
a_pos2 INTEGER;
시작
res.v_host := NULL;
res.v_path := NULL;
res.v_query := NULL;
a_pos1 := instr(v_url, '//');
만약 a_pos1 = 0이면
반환 해상도;
종료하면;
a_pos2 := instr(v_url, '/', a_pos1 + 2);
만약 a_pos2 = 0이면
res.v_host := substr(v_url, a_pos1 + 2);
res.v_path := '/';
반환 해상도;
종료하면;
res.v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2);
a_pos1 := instr(v_url, '?', a_pos2 + 1);
만약 a_pos1 = 0이면
res.v_path := substr(v_url, a_pos2);
반환 해상도;
종료하면;
res.v_path := substr(v_url, a_pos2, a_pos1 - a_pos2);
res.v_query := substr(v_url, a_pos1 + 1);
반환 해상도;
끝;
$$ 언어 plpgsql;
이 함수는 다음과 같이 사용될 수 있습니다:
SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz');
예 35-8여러 가지를 사용하는 프로시저를 포팅하는 방법을 보여줍니다. Oracle에만 해당되는 기능입니다.
예 35-8. 프로시저 포팅PL/SQL에스포츠 토토/pgSQL
오라클 버전:
프로시저 생성 또는 교체 cs_create_job(v_job_id IN INTEGER) IS
a_running_job_count INTEGER;
PRAGMA AUTONOMOUS_TRANSACTION;(1)시작
독점 모드에서 LOCK TABLE cs_jobs;(2)end_stamp가 NULL인 cs_jobs에서 a_running_job_count INTO 개수(*) 선택;
IF a_running_job_count 0 그러면
커밋; -- 자유 잠금(3)raise_application_error(-20000, '새 작업을 생성할 수 없습니다: 작업이 현재 실행 중입니다.');
종료하면;
cs_active_job에서 삭제;
cs_active_job(job_id) 값(v_job_id)에 삽입;
시작
INSERT INTO cs_jobs(job_id, start_stamp) VALUES(v_job_id, sysdate);
예외
dup_val_on_index가 NULL일 때; -- 이미 존재하더라도 걱정하지 마세요.
끝;
커밋;
끝;
/
오류 표시
이러한 절차는 다음으로 쉽게 변환될 수 있습니다.PostgreSQL함수 돌아오는 중무효. 이 절차는 특히 흥미로운 점은 우리에게 몇 가지를 가르쳐 줄 수 있기 때문입니다. 것들:
이 절차를 다음으로 포팅할 수 있는 방법입니다.스포츠 토토/pgSQL:
함수 생성 또는 교체 cs_create_job(v_job_id 정수) $$로 void를 반환합니다.
선언
a_running_job_count 정수;
시작
독점 모드에서 LOCK TABLE cs_jobs;
SELECT 개수(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp가 NULL입니다.
IF a_running_job_count 0 그러면
RAISE EXEPTION '새 작업을 생성할 수 없습니다. 작업이 현재 실행 중입니다.';(1)END IF;
cs_active_job에서 삭제;
cs_active_job(job_id) 값(v_job_id)에 삽입;
시작
INSERT INTO cs_jobs(job_id, start_stamp) VALUES(v_job_id, now());
예외
WHEN 고유_위반 THEN(2)-- 이미 존재하더라도 걱정하지 마세요.
끝;
반품;
끝;
$$ 언어 plpgsql;
이 섹션에서는 다음과 같은 경우에 주의해야 할 몇 가지 다른 사항을 설명합니다. 오라클 포팅PL/SQL기능을PostgreSQL.
에스포츠 토토/pgSQL, 때 예외는에 의해 포착됩니다.예외절, 블록 이후의 모든 데이터베이스 변경시작자동으로 롤백됩니다. 즉, 동작은 Oracle에서 얻을 수 있는 것과 동일합니다. 와 함께
시작
세이브포인트 s1;
... 코드는 여기에 ...
예외
언제 ... 그때
s1으로 롤백합니다.
... 코드는 여기에 ...
언제 ... 그때
s1으로 롤백합니다.
... 코드는 여기에 ...
끝;
다음을 사용하는 Oracle 프로시저를 번역하는 경우세이브포인트그리고다음으로 롤백이 스타일에서는 작업이 쉽습니다: 그냥 생략하세요세이브포인트그리고다음으로 롤백. 절차가 있는 경우 을 사용하는세이브포인트그리고다음으로 롤백몇몇은 다른 방식으로 실제적인 생각이 필요할 것입니다.
그스포츠 토토/pgSQL버전실행다음과 유사하게 작동합니다PL/SQL버전이 있지만
사용하는 것을 기억하기 위해quote_literal(텍스트)그리고quote_string(텍스트)설명된 대로섹션
35.6.5. 유형의 구성'SELECT * FROM $1' 실행;작동하지 않습니다
이 기능을 사용하지 않는 한.
포스트그레SQL두 개를 줍니다 실행을 최적화하기 위한 함수 생성 수정자:"변동성"(기능 여부 동일한 인수가 주어지면 항상 동일한 결과를 반환합니다) 그리고"엄격함"(어떠한지 인수가 null인 경우 함수는 null을 반환합니다. 상담하세요PostgreSQL : 문서 : 8.0 : 스포츠 토토 사이트 만들기자세한 내용은 참조 페이지입니다.
이러한 최적화 속성을 사용할 때 귀하의함수 생성문은 다음과 같습니다 이런 것:
CREATE FUNCTION foo(...) 정수를 $$로 반환합니다. ... $$ LANGUAGE plpgsql STRICT IMMUTABLE;
이 섹션에는 다음 세트에 대한 코드가 포함되어 있습니다.
오라클 호환입력함수
포팅 작업을 단순화하는 데 사용할 수 있습니다.
--
-- Oracle의 대응 기능을 모방한 instr 함수
-- 구문: instr(string1, string2, [n], [m]) 여기서 []는 선택적 매개변수를 나타냅니다.
--
-- n번째 문자부터 시작하여 string1에서 m번째 발생을 검색합니다.
-- 문자열2의 n이 음수이면 뒤로 검색합니다. m이 전달되지 않으면,
-- 1로 가정합니다(검색은 첫 번째 문자부터 시작됩니다).
--
CREATE FUNCTION instr(varchar, varchar) 정수를 $$로 반환합니다.
선언
위치 정수;
시작
위치:= instr($1, $2, 1);
반환 위치;
끝;
$$ LANGUAGE plpgsql 엄격한 불변;
CREATE FUNCTION instr(string varchar, string_to_search varchar, beg_index 정수)
$$로 정수를 반환합니다.
선언
위치 정수 NOT NULL DEFAULT 0;
temp_str varchar;
정수를 구걸하다;
길이 정수;
ss_length 정수;
시작
IF beg_index 0 그러면
temp_str := substring(string FROM beg_index);
pos := position(string_to_search IN temp_str);
IF pos = 0이면
0을 반환합니다.
그 외
RETURN pos + beg_index - 1;
종료하면;
그 외
ss_length := char_length(string_to_search);
길이 := char_length(string);
구걸 := 길이 + 구걸_색인 - ss_length + 2;
구걸하는 동안 0 LOOP
temp_str := substring(string FROM beg FOR ss_length);
pos := position(string_to_search IN temp_str);
IF pos 0 THEN
반환 구걸;
종료하면;
구걸하다 := 구걸하다 - 1;
엔드 루프;
0을 반환합니다.
종료하면;
끝;
$$ LANGUAGE plpgsql 엄격한 불변;
CREATE FUNCTION instr(string varchar, string_to_search varchar,
beg_index 정수, 발생_index 정수)
$$로 정수를 반환합니다.
선언
위치 정수 NOT NULL DEFAULT 0;
발생_번호 정수 NOT NULL DEFAULT 0;
temp_str varchar;
정수를 구걸하다;
나는 정수;
길이 정수;
ss_length 정수;
시작
IF beg_index 0 그러면
구걸 := 구걸_index;
temp_str := substring(string FROM beg_index);
FOR i IN 1..occur_index LOOP
pos := position(string_to_search IN temp_str);
I = 1이면
구걸 := 구걸 + pos - 1;
그 외
구걸하다 := 구걸하다 + pos;
종료하면;
temp_str := substring(string FROM beg + 1);
엔드 루프;
IF pos = 0이면
0을 반환합니다.
그 외
반환 구걸;
종료하면;
그 외
ss_length := char_length(string_to_search);
길이 := char_length(string);
구걸 := 길이 + 구걸_색인 - ss_length + 2;
구걸하는 동안 0 LOOP
temp_str := substring(string FROM beg FOR ss_length);
pos := position(string_to_search IN temp_str);
IF 위치 0 THEN
발생_번호 := 발생_번호 + 1;
IF 발생_번호 = 발생_인덱스 THEN
반환 구걸;
종료하면;
종료하면;
구걸하다 := 구걸하다 - 1;
엔드 루프;
0을 반환합니다.
종료하면;
끝;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;