SQL$HELP72.HLB  —  DECLARE  Extended Dynamic CURSOR
    Declares an extended dynamic cursor. An extended dynamic DECLARE
    CURSOR statement is a DECLARE CURSOR statement in which both the
    cursor name and the SELECT statement are supplied in parameters
    at run time.

    See the DECLARE CURSOR for a detailed description of statement
    elements that apply to both dynamic and nondynamic DECLARE CURSOR
    statements.

1  –  Environment

    You can use the extended dynamic DECLARE CURSOR statement:

    o  Embedded in host language programs to be precompiled

    o  As part of a procedure in an SQL module

2  –  Format

  (B)0DECLARE <cursor-name-parameter> qqqqqqqqqqqqqqqk                
  lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj                
  mwqqqwqqqqqqqqqqqqqqqqwq> TABLE CURSOR qwqqqqqqqqqqqqqqqqwk     
   x   tq> INSERT ONLY qu                 mq> with-clause qjx     
   x   tq> READ ONLY qqqu                                   x     
   x   mq> UPDATE ONLY qj                                   x     
   x lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj     
   x mqq> FOR qqq> <statement-id-parameter> qqqqqqqqqqqqwqqqqqqq> 
   mqwqqqqqqqqqqqqqqwwqqqqqqqqqqwwq> LIST CURSOR FOR qk x         
     tq> READ ONLY qjm> SCROLL qjx                    x x         
     mq> INSERT ONLY qqqqqqqqqqqqj                    x x         
   lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj x         
   mq> <statement-id-parameter> qqqqqqqqqqqqqqqqqqqqqqqqj         
                                                                  

  (B)0with-clause =                                           
                                                          
  qqq> WITH qq> HOLD qwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqwq> 
                      mq> PRESERVE qqwq> ON COMMIT qqqu   
                                     tq> ON ROLLBACK qu   
                                     tq> ALL qqqqqqqqqu   
                                     mq> NONE qqqqqqqqj   
                                                          

3  –  Arguments

3.1  –  cursor-name-parameter

    Contains the name of the cursor you want to declare. Use a
    character string parameter to hold the cursor name that the
    program supplies at run time.

3.2  –  FOR statement id parameter

    A parameter that contains an integer that identifies a prepared
    SELECT statement. Use an integer parameter to hold the statement
    identifier that SQL generates and assigns to the parameter when
    SQL executes a PREPARE statement.

3.3  –  INSERT_ONLY

    Specifies that a new list or a new row is created or opened.

3.4  –  LIST_CURSOR_FOR

    Specifies that you are declaring a cursor to access the elements
    in a list.

3.5  –  preserve-clause

    Syntax options:

       PRESERVE ON COMMIT
       PRESERVE ON ROLLBACK
       PRESERVE ALL
       PRESERVE NONE

    Specifies when a cursor remains open.

    o  PRESERVE ON COMMIT

       On commit, all cursors close except those defined with the
       WITH HOLD PRESERVE ON COMMIT syntax. On rollback, all cursors
       close including those defined with the WITH HOLD PRESERVE ON
       COMMIT syntax.

       This is the same as specifying the WITH HOLD clause without
       any preserve options.

    o  PRESERVE ON ROLLBACK

       On rollback, all cursors close except those defined with the
       WITH HOLD PRESERVE ON ROLLBACK syntax. On commit, all cursors
       close including those defined with the WITH HOLD PRESERVE ON
       ROLLBACK syntax.

    o  PRESERVE ALL

       All cursors remain open after commit or rollback. Cursors
       close with the CLOSE statement or when the session ends.

    o  PRESERVE NONE

       All cursors close after a close, commit, or rollback
       statement, when the program stops, or when you exit from
       interactive SQL.

       This is the same as not specifying the WITH HOLD clause at
       all.

3.6  –  READ_ONLY

    Specifies that the cursor is not used to update the database.

3.7  –  SCROLL

    Specifies that Oracle Rdb can read the items in a list from
    either direction (up or down) or at random.

3.8  –  TABLE_CURSOR_FOR

    Specifies that you are declaring a cursor to access the rows in a
    table.

3.9  –  UPDATE_ONLY

    Specifies that the cursor is used to update the database.

3.10  –  WITH_HOLD

    Indicates that the cursor remain open and maintain its position
    after the transaction ends. This is called a holdable cursor.

4  –  Example

    Example 1: Using parameters for statement and cursor names

    The following example shows two procedures from the online sample
    program SQL$MULTI_STMT_DYN.SQLADA. These procedures show the use
    of parameters for statement and cursor names.

    .
    .
    .
    -- This procedure prepares a statement for dynamic execution from the string
    -- passed to it.  This procedure can prepare any number of statements
    -- because the statement is passed to it as the parameter, cur_procid.

    procedure PREPARE_SQL is
        CUR_CURSOR : string(1..31) := (others => ' ');
        CUR_PROCID : integer := 0;
        CUR_STMT : string(1..1024) := (others => ' ');

    begin
    -- Allocate separate SQLDAs for parameter markers (sqlda_in) and select list
    -- items (sqlda_out).  Assign the value of the constant MAXPARMS (set in the
    -- declarations section) to the SQLN field of both SQLDA structures. SQLN
    -- specifies to SQL the maximum size of the SQLDA.

    sqlda_in := new sqlda_record;
    sqlda_in.sqln := maxparms;
    sqlda_out := new sqlda_record;
    sqlda_out.sqln := maxparms;

    -- Assign the SQL statement that was constructed in the procedure
    -- CONSTRUCT_SQL to the variable cur_stmt.

    cur_stmt := sql_stmt;

    -- Use the PREPARE...SELECT LIST statement to prepare the dynamic statement
    -- and write information about any select list items in it to sqlda_out.
    -- It prepares a statement for dynamic execution from the string passed to
    -- it.  It also writes information about the number and data type of any
    -- select list items in the statement to an SQLDA (specifically, the
    -- sqlda_out SQLDA specified).
    --
    -- Note that the PREPARE statement could have prepared the statement without
    -- writing to an SQLDA.  Instead, a separate DESCRIBE...SELECT LIST statement
    -- would have written information about any select list items to an SQLDA.
    EXEC SQL PREPARE :cur_procid SELECT LIST INTO :sqlda_out FROM :cur_stmt;
    case sqlca.sqlcode is
        when sql_success => null;
        when others => raise syntax_error;
    end case;

    -- Use the DESCRIBE...MARKERS statement to write information about any
    -- parameter markers in the dynamic statement to sqlda_in.  This statement
    -- writes information to an SQLDA (specifically, the sqlda_in SQLDA
    -- specified) about the number and data type of any parameter markers in
    -- the prepared dynamic statement.  Note that SELECT statements may also
    -- have parameter markers.

    EXEC SQL DESCRIBE :cur_procid MARKERS INTO sqlda_in;
    case sqlca.sqlcode is
        when sql_success => null;
        when others => raise syntax_error;
    end case;

    -- If the operation is "Read," create a unique name for the cursor name
    -- so that the program can pass the cursor name to the dynamic DECLARE
    -- CURSOR statement.

    if cur_op(1) = 'R' then
        cur_cursor(1) := 'C';
        cur_cursor(2..name_strlng) := cur_name(1..name_strlng - 1);

    -- Declare the dynamic cursor.

        EXEC SQL DECLARE :cur_cursor CURSOR FOR :cur_procid;
        case sqlca.sqlcode is
            when sql_success => null;
            when others => raise syntax_error;
        end case;
    end if;

    number_of_procs := number_of_procs + 1;
    sqlda_in_array(number_of_procs) := sqlda_in;
    sqlda_out_array(number_of_procs) := sqlda_out;
    procedure_names(number_of_procs) := cur_name;
    procedure_ids(number_of_procs) := cur_procid;
    if cur_op(1) = 'R' then
        cursor_names(number_of_procs) := cur_cursor;
    end if;

    exception
        when syntax_error =>
            sql_get_error_text(get_error_buffer,get_error_length);
            put_line(get_error_buffer(1..integer(get_error_length)));
            put("Press RETURN to continue. ");
            get_line(terminal,release_screen,last);
            new_line;
    end PREPARE_SQL;
    .
    .
    .
    begin  -- procedure body DISPLAY_DATA

    -- Before displaying any data, allocate buffers to hold the data
    -- returned by SQL.
    --
        allocate_buffers;

    -- Allocate and assign SQLDAs for the requested SQL procedure.
    --
    sqlda_in := new sqlda_record;
    sqlda_in := sqlda_in_array(stmt_index);
    sqlda_out := new sqlda_record;
    sqlda_out := sqlda_out_array(stmt_index);
    cur_cursor := cursor_names(stmt_index);
    -- Open the previously declared cursor.  The statement specifies
    -- an SQLDA (specifically, sqlda_in) as the source of addresses for any
    -- parameter markers in the cursor's SELECT statement.
    --
    EXEC SQL OPEN :cur_cursor USING DESCRIPTOR sqlda_in;
    case sqlca.sqlcode is
        when sql_success => null;
        when others => raise unexpected_error;
    end case;

    -- Fetch the first row from the result table.  This statement fetches a
    -- row from the opened cursor and writes it to the addresses specified
    -- in an SQLDA (specifically, sqlda_out).
    --
    EXEC SQL FETCH :cur_cursor USING DESCRIPTOR sqlda_out;
    case sqlca.sqlcode is
    --  Check to see if the result table has any rows.
        when sql_success => null;
        when stream_eof =>
            put_line("No records found.");
            new_line;
        when others => raise unexpected_error;
    end case;

    -- Set up a loop to display the first row, then fetch and display second
    -- and subsequent rows.

        rowcount := 0;
        while sqlca.sqlcode = 0 loop
            rowcount := rowcount + 1;
    --      Execute the DISPLAY_ROW procedure.
            display_row;
    --      To only display 5 rows, exit the loop if the loop counter
    --      equals MAXROW (coded as 5 in this program).
            if rowcount = maxrows then exit; end if;
    --      Fetch another row, exit the loop if no more rows.
            EXEC SQL FETCH :cur_cursor USING DESCRIPTOR sqlda_out;
            case sqlca.sqlcode is
                when sql_success => null;
                when stream_eof => exit;
                when others => raise unexpected_error;
            end case;
        end loop;
    -- Close the cursor.
    EXEC SQL CLOSE :cur_cursor;
    case sqlca.sqlcode is
        when sql_success => null;
        when others => raise unexpected_error;
    end case;
    exception
        when unexpected_error =>
            sql_get_error_text(get_error_buffer,get_error_length);
            EXEC SQL ROLLBACK;
            put_line("This condition was not expected.");
            put_line(get_error_buffer(1..integer(get_error_length)));
            put("Press RETURN to continue. ");
            get_line(terminal,release_screen,last);

    -- Stop and let the user look before returning.
        skip;
        put_line("Press RETURN to proceed. ");
        get_line(terminal,release_screen,last);

    end DISPLAY_DATA;
Close Help