Два критерію професіоналізму програмування Oracle: вживання посилання на курсор в програмі, Інтеграція додатків і даних, Бази даних, статті

Церква була відчинена, за огорожею стояло кілька саней;
по паперті ходили люди. "Сюди! Сюди!" – Закричало кілька голосів …
А. С. Пушкін, "Заметіль"

Зміст



Анотація


Розглядаються посилання на курсор, представляють собою інструмент просунутого програмування в Oracle. Наводяться приклади роботи через посилання на курсор в програмах на PL / SQL і Java і в SQL * Plus.

Посилання на курсор


У пору мого навчання в технічному ВНЗ люди, як і зараз, були схильні називати себе як завгодно, і в народі побутував критерій справжнього математика. Право їм назватися віддавалася тому, хто знав, що таке поле Галуа. Так і не ставши математиком, не беруся судити про коректність цього критерію (здається, він дитячий), проте, займаючись Oracle, можу запропонувати інший критерій професіоналізму: для програміста цієї СУБД.

У діалекті SQL, придуманому фірмою Oracle, є багато різних конструкцій, не всякому відомих; наприклад, аналітичні функції, або ж кошти для роботи з рукотворними об'єктами. Але це речі специфічні, не кожному програмістові потрібні, а ось посилання на курсор – явище безумовно загального характеру.

Посилання на курсор дає можливість не заводити структури курсору (CURSOR … IS …) в клієнтській програмі, а обмежитися в ній виділенням пам'яті тільки для адреси курсора, в той час як сам курсор буде розташовуватися цілком в СУБД. Програміст здатний прожити і без посилань на курсор, однак ті можуть дати програмами помітні конструктивні вигоди:


Оскільки принципово для програмування посилання на курсори не потрібні, більшість розробників обходиться звичайним способом спілкування з СУБД. Вигоди ж витягають програмісти, яких і можна в даному контексті визнати професіоналами.

Посилання на курсор реалізовані в Oracle програмно і в SQL. У програмі вони реалізуються у вигляді спеціальної змінної, і саме цей варіант показаний в цій статті. Клієнтськими середовищами виступатимуть PL / SQL, SQL * Plus і Java.

Опис посилання на курсор і використання в PL / SQL


На якому б мовою ви не спілкувалися з БД за допомогою посилання на курсор, без програмування на PL / SQL не обійтися. Формальна сторона роботи з посиланням на курсор в PL / SQL обставлена ​​просто.

По-перше, щоб завести в PL / SQL змінну-посилання на курсор, потрібно спочатку описати її тип. Це робиться в розділі опису за допомогою пропозиції TYPE:

TYPE імя_тіпа_ссилкі_на_курсор IS REF CURSOR [RETURN тіп_запісі];

Якщо конструкція RETURN присутній, посилання на курсор називається суворої, якщо ні – нестрогой. Нестрога може посилатися на будь курсор (запит), а сувора – тільки на той, що повертає результат зазначеного типу.

Приклад опису обох типів посилання на курсор:

DECLARE
TYPE any_curtype IS REF CURSOR;
generic_curvar any_curtype;

TYPE departments_curtype IS REF CURSOR RETURN dept%ROWTYPE;
departments_cur departments_curtype;

BEGIN NULL; END;
/

Відкриття курсору за допомогою змінної-посилання на курсор:

OPEN ссилка_на_курсор FOR предложеніе_SELECT;

Команди FETCH і CLOSE використовуються як завжди, тільки замість імені курсору вказуємо ім'я посилання на курсор.

По-друге, для зручності програмування підтримується "системний" тип SYS_REFCURSOR нестрогой посилання на курсор. Так, в блоці вище, в розділі опису можна було б не приводити пропозицію TYPE, а відразу сказати:

generic_curvar SYS_REFCURSOR;

Тип SYS_REFCURSOR скорочує текст програми, а іноді дозволяє і обійтися без створення службового пакета (приклад чого в цій статті не розглядається).

Створення пакета в PL / SQL


Наведені нижче приклади в кожній з трьох середовищ програмування будуть використовувати для доступу до БД через посилання на курсор один і той же пакет. У реальному житті саме на подібний пакет і ляже опис необхідної програмної логіки. Тут же він в ім'я наочності влаштований максимально просто, (майже) без будь-якої програмно-прикладної логіки, але ця обставина і забезпечує йому універсальність.

Видамо в SQL * Plus:

CONNECT scott/tiger

CREATE OR REPLACE PACKAGE generic_ref_cursor AS
PROCEDURE get_ref_cursor(sqlselect IN VARCHAR2, rc OUT sys_refcursor);
END;
/

CREATE OR REPLACE PACKAGE BODY generic_ref_cursor AS
PROCEDURE get_ref_cursor (sqlselect IN VARCHAR2, rc OUT sys_refcursor) AS
BEGIN
OPEN rc FOR sqlselect;
END;
END;
/

У реальній практиці такого вихолощеному пакету цілком може знайтися своє місце, однак часто будуть використовуватися і інші, спільні з наведеним вище тільки тим, що


  1. в тілі буде обов'язково бути присутнім пропозицію OPEN
  2. серед параметрів повинен бути присутнім вихідний типу посилання на курсор (можливо суворої).

Останнє регламентується виключно логікою програми та організації програми.

Приклад програмування в PL / SQL


У цьому прикладі з допомогою нашого пакета відкриваємо курсор і передаємо посилання на курсор в програму. Витяг результатів пропозицій SELECT виконується окремими процедурами, причому для результатів з різною структурою ми змушені передбачити різні процедури вилучення. Це – плата за мінімалізм і спільність пакета.

Видамо в SQL * Plus:

SET SERVEROUTPUT ON

DECLARE
lrc SYS_REFCURSOR;

PROCEDURE fetchandclose ( rc IN sys_refcursor ) IS
somename VARCHAR2 ( 20 );

BEGIN

DBMS_OUTPUT.PUT_LINE ( “” );

LOOP

FETCH rc INTO somename;

EXIT WHEN rc%NOTFOUND;

DBMS_OUTPUT.PUT_LINE ( somename );

END LOOP;

CLOSE rc;

END;

PROCEDURE fetch2andclose ( rc IN sys_refcursor ) IS
somename VARCHAR2 ( 20 );
somenumber NUMBER;

BEGIN

DBMS_OUTPUT.PUT_LINE ( “” );

LOOP

FETCH rc INTO somename, somenumber;

EXIT WHEN rc%NOTFOUND;

DBMS_OUTPUT.PUT_LINE (RPAD (somename, 10, "") / / somenumber);

END LOOP;

CLOSE rc;

END;

BEGIN
– Приклади:
generic_ref_cursor.get_ref_cursor ( “SELECT ename FROM emp“, lrc );
fetchandclose ( lrc );

generic_ref_cursor.get_ref_cursor ( “SELECT dname FROM dept“, lrc );
fetchandclose ( lrc );

generic_ref_cursor.get_ref_cursor ( “SELECT job, sal FROM emp”, lrc );
fetch2andclose ( lrc );
END;
/

(Щоб не ускладнювати приклад, результат на екрані майже не оформлюється).

Звернемо увагу: програмами, що обробляють за загальною схемою однотипні курсори, ми передаємо не тексти запиту, а посилання на вже відкритий і динамічно (а не статично, як у випадку його визначення в окремому пакеті) сформований курсор.

Приклад програмування в SQL * Plus


SQL * Plus дозволяє заводити власні змінні, в тому числі і типу нестрогой посилання на курсор. Відкривається курсор, як і у прикладі вище, нашим пакетом, а ось витяг можливо звичайної командою PRINT. Ця команда вміє розпізнавати структуру фактичного курсора, що дуже зручно для роботи.

Видамо в SQL * Plus:

VARIABLE refcur REFCURSOR

BEGIN
generic_ref_cursor.get_ref_cursor

( “SELECT ename, sal FROM emp”, :refcur );

END;
/

PRINT refcur

BEGIN
generic_ref_cursor.get_ref_cursor

( “SELECT * FROM emp”, :refcur );

END;
/

PRINT refcur

На відміну від попереднього прикладу команда PRINT закриває курсор, так що вторинна видача

PRINT refcur

призведе до помилки.

Приклад програмування в Java


У клієнтській програмі на Java звертатися до БД через посилання на курсор можна за допомогою власних розширень, зроблених фірмою Oracle в реалізації нею драйвера JDBC. У програмі нижче передбачається ім'я СУБД MYDB. Зверніть увагу, що текст із запитом SQL передається нашому пакету об'єктом класу CallableStatement, а витяг в програму посилання на курсор робиться після приведення цього об'єкта до суто Oracle "івської класу OracleCallableStatement.

Отримання в програму посилання на курсор відповідає формуванню об'єкта класу ResultSet, обробка якого робиться стандартно.

Видача другого запиту в програмі нижче демонструє можливість використання одного і того ж пакету для отримання результату різної структури. Очевидно, за своєю гнучкості ця техніка знаходиться посередині між тим, що мається на PL / SQL і в SQL * Plus.

Підготуємо файл GenericRefCursor.java:






import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import oracle.jdbc.driver.OracleCallableStatement;
import oracle.jdbc.driver.OracleTypes;


public class GenericRefCursor
{

public static void main ( String[] args )
{
 try
 {

DriverManager.registerDriver
( new oracle.jdbc.driver.OracleDriver ( ) );


cn = DriverManager.getConnection

( “jdbc:oracle:oci:@mydb”, “scott”, “tiger” );


CallableStatement cst;
OracleCallableStatement ocst;
ResultSet rs;


cst = cn.prepareCall

( “BEGIN generic_ref_cursor.get_ref_cursor ( ?, ? ); END;” );

cst.setString ( 1, “SELECT sal FROM emp” );
cst.registerOutParameter ( 2, OracleTypes.CURSOR );


cst.execute ( );


ocst = ( OracleCallableStatement ) cst;


rs = ocst.getCursor ( 2 );


while (rs.next ()) {System.out.println (rs.getInt (1));}


/ * Новий запит … * /
cst.setString ( 1, “SELECT dname, loc FROM dept” );
cst.execute ( );
rs = ocst.getCursor ( 2 );
while ( rs.next ( ) )
{System.out.println (rs.getString (1) + rs.getString (2));}


/ * … і так далі, запит за запитом * /


cst.close ( );

 }
 catch ( Exception e ) { System.out.println ( e ); }
}

}


В ОС оттрансліруем клас GenericRefCursor і виконаємо програму:

>javac GenericRefCursor.java
>java GenericRefCursor

Обмеження використання посилання на курсор


Думки, які виникають з приводу можливого використання посилань на курсор в програмі, кілька осідають існуючими обмеженнями, частина яких, якщо вдуматися, мають свою логіку. Як згадувалося, посилання на курсор не представлені типом SQL (до деякої міри це природно), і не можуть зберігатися в якості змінних пакета PL / SQL. Більш повно:

Інші статті по продуктах Oracle з рубрики "Майстерня Oracle"

  • Лінійка продуктів Oracle 10g
  • Звернутися в Interface Ltd. за додатковою інформацією / з питання придбання продуктів
  • Придбати продукти Oracle в електронному магазині ITShop.ru
  • Курси по продуктах фірми Oracle

  • Схожі статті:


    Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

    Коментарів поки що немає.

    Ваш отзыв

    Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

    *

    *