Oracle12c中PL/SQL(DBMS_SQL)新特性之隱式語句結果
隱式資料結果特性將能簡化從其他資料庫到Oracle12c儲存過程遷移。
1. 背景
T-SQL中允許查詢結果的隱式返回。例如:下面T-SQL儲存過程隱式返回查詢結果。
CREATE PROCEDURE Get_Results
( @p_id int )
AS
SELECT dscpt, crt_date FROM t1 WHERE id = @p_id
RETURN 0
GO
透過DBMS_SQL包中的RETURN_RESULT過程,Oracle 12c目前支援類似的功能。這在實施遷移時非常有用。
2. RETURN_RESULT
不是顯式定義參照遊標(ref cursor)輸出引數,DBMS_SQL包中的RETURN_RESULT過程允許結果隱式傳出,看下例。
CREATE table t1 (
id NUMBER,
dscpt VARCHAR2(30),
crt_date DATE
);
INSERT INTO t1 VALUES (1, 'The value 1', SYSDATE-2);
INSERT INTO t1 VALUES (2, 'The value 2', SYSDATE-1);
INSERT INTO t1 VALUES (3, 'The value 3', SYSDATE);
COMMIT;
現在我們建立一個過程來返回一個或多個結果集。
CREATE OR REPLACE PROCEDURE get_results (p_id IN NUMBER DEFAULT NULL)
AS
l_cursor_1 SYS_REFCURSOR;
l_cursor_2 SYS_REFCURSOR;
BEGIN
IF p_id IS NOT NULL THEN
OPEN l_cursor_1 FOR
SELECT dscpt, crt_date
FROM t1
WHERE id = p_id;
DBMS_SQL.RETURN_RESULT(l_cursor_1);
END IF;
OPEN l_cursor_2 FOR
SELECT COUNT(*)
FROM t1;
DBMS_SQL.RETURN_RESULT(l_cursor_2);
END;
/
我們從sql*plus中執行該過程時,將會自動顯式顯示語句結果。
SQL> EXEC get_results(1);
PL/SQL procedure successfully completed.
ResultSet #1
DESCRIPTION CREATED_DATE
------------------------------ --------------------
The value 1 06-JUL-2013 21:19:45
1 row selected.
ResultSet #2
COUNT(*)
----------
3
1 row selected.
SQL> EXEC get_my_results;
PL/SQL procedure successfully completed.
ResultSet #1
COUNT(*)
----------
3
1 row selected.
SQL>
透過RETURN_RESULT過程返回DBMS_SQL的遊標時也會存在一些限制和不足。
3. GET_NEXT_RESULT
一般來說,我們希望透過客戶端應用來處理這些結果集,這可以透過DBMS_SQL包的 GET_NEXT_RESULT過程來解決。
下例透過DBMS_SQL包來執行該過程。由於過程返回不同記錄結構的結果集,我們必須描述這些結果集以便進行處理。這可以透過結果集的列數來進行判斷。
SET SERVEROUTPUT ON
DECLARE
l_sql_cursor PLS_INTEGER;
l_ref_cursor SYS_REFCURSOR;
l_return PLS_INTEGER;
l_col_cnt PLS_INTEGER;
l_desc_tab DBMS_SQL.desc_tab;
l_count NUMBER;
l_dscpt t1.dscpt%TYPE;
l_crt_date t1.crt_date%TYPE;
BEGIN
-- 執行過程
l_sql_cursor := DBMS_SQL.open_cursor(treat_as_client_for_results => TRUE);
DBMS_SQL.parse(c => l_sql_cursor,
statement => 'BEGIN get_results(1); END;',
language_flag => DBMS_SQL.native);
l_return := DBMS_SQL.execute(l_sql_cursor);
-- 迴圈遍歷每個結果集
LOOP
-- 獲取下個結果集
BEGIN
DBMS_SQL.get_next_result(l_sql_cursor, l_ref_cursor);
EXCEPTION
WHEN NO_DATA_FOUND THEN
EXIT;
END;
-- 檢查結果集列數
l_return := DBMS_SQL.to_cursor_number(l_ref_cursor);
DBMS_SQL.describe_columns (l_return, l_col_cnt, l_desc_tab);
l_ref_cursor := DBMS_SQL.to_refcursor(l_return);
-- 根據列數處理結果集
CASE l_col_cnt
WHEN 1 THEN
DBMS_OUTPUT.put_line('The column is COUNT:');
FETCH l_ref_cursor
INTO l_count;
DBMS_OUTPUT.put_line('l_count=' || l_count);
CLOSE l_ref_cursor;
WHEN 2 THEN
DBMS_OUTPUT.put_line('The columns are DSCPT and CRT_DATE:');
LOOP
FETCH l_ref_cursor
INTO l_dscpt, l_crt_date;
EXIT WHEN l_ref_cursor%NOTFOUND;
DBMS_OUTPUT.put_line('l_dscpt=' || l_dscpt || ' ' ||
'l_crt_date=' || TO_CHAR(l_crt_date, 'DD-MON-YYYY'));
END LOOP;
CLOSE l_ref_cursor;
ELSE
DBMS_OUTPUT.put_Line('I wasn''t expecting that!');
END CASE;
END LOOP;
END;
/
The columns are DSCPT and CRT_DATE:
l_dscpt=The value 1 l_crt_date=06-JUL-2013
The column is COUNT:
l_count=3
PL/SQL procedure successfully completed.
SQL>
透過過程GET_NEXT_RESULT返回DBMS_SQL中的遊標時也會有一些限制和不足。
1. 背景
T-SQL中允許查詢結果的隱式返回。例如:下面T-SQL儲存過程隱式返回查詢結果。
CREATE PROCEDURE Get_Results
( @p_id int )
AS
SELECT dscpt, crt_date FROM t1 WHERE id = @p_id
RETURN 0
GO
透過DBMS_SQL包中的RETURN_RESULT過程,Oracle 12c目前支援類似的功能。這在實施遷移時非常有用。
2. RETURN_RESULT
不是顯式定義參照遊標(ref cursor)輸出引數,DBMS_SQL包中的RETURN_RESULT過程允許結果隱式傳出,看下例。
CREATE table t1 (
id NUMBER,
dscpt VARCHAR2(30),
crt_date DATE
);
INSERT INTO t1 VALUES (1, 'The value 1', SYSDATE-2);
INSERT INTO t1 VALUES (2, 'The value 2', SYSDATE-1);
INSERT INTO t1 VALUES (3, 'The value 3', SYSDATE);
COMMIT;
現在我們建立一個過程來返回一個或多個結果集。
CREATE OR REPLACE PROCEDURE get_results (p_id IN NUMBER DEFAULT NULL)
AS
l_cursor_1 SYS_REFCURSOR;
l_cursor_2 SYS_REFCURSOR;
BEGIN
IF p_id IS NOT NULL THEN
OPEN l_cursor_1 FOR
SELECT dscpt, crt_date
FROM t1
WHERE id = p_id;
DBMS_SQL.RETURN_RESULT(l_cursor_1);
END IF;
OPEN l_cursor_2 FOR
SELECT COUNT(*)
FROM t1;
DBMS_SQL.RETURN_RESULT(l_cursor_2);
END;
/
我們從sql*plus中執行該過程時,將會自動顯式顯示語句結果。
SQL> EXEC get_results(1);
PL/SQL procedure successfully completed.
ResultSet #1
DESCRIPTION CREATED_DATE
------------------------------ --------------------
The value 1 06-JUL-2013 21:19:45
1 row selected.
ResultSet #2
COUNT(*)
----------
3
1 row selected.
SQL> EXEC get_my_results;
PL/SQL procedure successfully completed.
ResultSet #1
COUNT(*)
----------
3
1 row selected.
SQL>
透過RETURN_RESULT過程返回DBMS_SQL的遊標時也會存在一些限制和不足。
3. GET_NEXT_RESULT
一般來說,我們希望透過客戶端應用來處理這些結果集,這可以透過DBMS_SQL包的 GET_NEXT_RESULT過程來解決。
下例透過DBMS_SQL包來執行該過程。由於過程返回不同記錄結構的結果集,我們必須描述這些結果集以便進行處理。這可以透過結果集的列數來進行判斷。
SET SERVEROUTPUT ON
DECLARE
l_sql_cursor PLS_INTEGER;
l_ref_cursor SYS_REFCURSOR;
l_return PLS_INTEGER;
l_col_cnt PLS_INTEGER;
l_desc_tab DBMS_SQL.desc_tab;
l_count NUMBER;
l_dscpt t1.dscpt%TYPE;
l_crt_date t1.crt_date%TYPE;
BEGIN
-- 執行過程
l_sql_cursor := DBMS_SQL.open_cursor(treat_as_client_for_results => TRUE);
DBMS_SQL.parse(c => l_sql_cursor,
statement => 'BEGIN get_results(1); END;',
language_flag => DBMS_SQL.native);
l_return := DBMS_SQL.execute(l_sql_cursor);
-- 迴圈遍歷每個結果集
LOOP
-- 獲取下個結果集
BEGIN
DBMS_SQL.get_next_result(l_sql_cursor, l_ref_cursor);
EXCEPTION
WHEN NO_DATA_FOUND THEN
EXIT;
END;
-- 檢查結果集列數
l_return := DBMS_SQL.to_cursor_number(l_ref_cursor);
DBMS_SQL.describe_columns (l_return, l_col_cnt, l_desc_tab);
l_ref_cursor := DBMS_SQL.to_refcursor(l_return);
-- 根據列數處理結果集
CASE l_col_cnt
WHEN 1 THEN
DBMS_OUTPUT.put_line('The column is COUNT:');
FETCH l_ref_cursor
INTO l_count;
DBMS_OUTPUT.put_line('l_count=' || l_count);
CLOSE l_ref_cursor;
WHEN 2 THEN
DBMS_OUTPUT.put_line('The columns are DSCPT and CRT_DATE:');
LOOP
FETCH l_ref_cursor
INTO l_dscpt, l_crt_date;
EXIT WHEN l_ref_cursor%NOTFOUND;
DBMS_OUTPUT.put_line('l_dscpt=' || l_dscpt || ' ' ||
'l_crt_date=' || TO_CHAR(l_crt_date, 'DD-MON-YYYY'));
END LOOP;
CLOSE l_ref_cursor;
ELSE
DBMS_OUTPUT.put_Line('I wasn''t expecting that!');
END CASE;
END LOOP;
END;
/
The columns are DSCPT and CRT_DATE:
l_dscpt=The value 1 l_crt_date=06-JUL-2013
The column is COUNT:
l_count=3
PL/SQL procedure successfully completed.
SQL>
透過過程GET_NEXT_RESULT返回DBMS_SQL中的遊標時也會有一些限制和不足。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8484829/viewspace-2120969/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle12c新特性(7)--如何在RMAN中執行SQL語句OracleSQL
- PLSQL Language Reference-PL/SQL子程式-PL/SQL函式結果快取-開啟函式結果快取SQL函式快取
- 分析後sql語句很快返回結果SQL
- Oracle12c中SQL最佳化(SQL TUNING)新特性之SQL計劃指令OracleSQL
- PL/SQL與DDL語句SQL
- PLSQL Language Reference-PL/SQL子程式-PL/SQL函式結果快取(二)SQL函式快取
- GOTO語句在PL/SQL中的應用GoSQL
- PL/SQL 動態sql語句例SQL
- PL/SQL 條件控制語句SQL
- PL/SQL迴圈控制語句SQL
- 使用SQL TRACE和TKPROF觀察SQL語句執行結果SQL
- SQL語句將查詢結果插入到另一張表中SQL
- 利用pl/sql執行本地的sql檔案中的sql語句SQL
- PLSQL Language Reference-PL/SQL語言基礎-表示式-PL/SQL表示式中的SQL函式SQL函式
- Oracle12c新特性之基本操作Oracle
- PLSQL Language Referenc-PL/SQL動態SQL-SQL隱碼攻擊-SQL隱碼攻擊技術-語句修改SQL
- Oracle11新特性——SQL快取結果集(五)OracleSQL快取
- Oracle11新特性——SQL快取結果集(三)OracleSQL快取
- 11g新特性之結果集快取快取
- SQL隱碼攻擊語句SQL
- Oracle PL/SQL 之 函式OracleSQL函式
- PL/SQL Developer中輸入SQL語句時如何自動提示欄位SQLDeveloper
- [20240607]PL/SQL中sql語句的註解.txtSQL
- pl/sql功能特性SQL
- PLSQL Language Referenc-PL/SQL控制語句-順序控制語句-NULLSQLNull
- PLSQL Language Referenc-PL/SQL控制語句-迴圈語句-FOR迴圈SQL
- PLSQL Language Referenc-PL/SQL控制語句-迴圈語句-CONTINUESQL
- PLSQL Language Referenc-PL/SQL控制語句-迴圈語句-EXIT WHENSQL
- PLSQL Language Referenc-PL/SQL控制語句-迴圈語句-基本迴圈(EXIT語句)SQL
- PLSQL Language Referenc-PL/SQL控制語句-迴圈語句-FOR迴圈-FOR迴圈中的索引SQL索引
- Oracle12c中容錯&效能新特性之表空間組Oracle
- Oracle12c中SQL最佳化新特性之自動重最佳化(automatic reoptimization)OracleSQL
- Oracle11新特性——PLSQL函式快取結果(一)OracleSQL函式快取
- Oracle11新特性——PLSQL函式快取結果(三)OracleSQL函式快取
- Oracle11新特性——PLSQL函式快取結果(二)OracleSQL函式快取
- 6.4. PL/SQL語法——6.4.5. 迴圈語句SQL
- 【PL/SQL 學習】隱式遊標學習SQL
- DBMS_SQLSQL