Pl sql cursor

hi to everyone
          this is my coding and i want you to make a slight adjustment to print in a format which i required..
DECLARE
department_no   emp.empno%TYPE;
   CURSOR cur
   IS
      SELECT *
        FROM emp
  order by deptno;
      BEGIN
   FOR i IN cur
   LOOP
      department_no := i.deptno;
      sys.DBMS_OUTPUT.put_line ('department  no is' || department_no);
      sys.DBMS_OUTPUT.put_line ('employee first name is' || i.ename);
      sys.DBMS_OUTPUT.put_line ('-------------------------');
   END LOOP;
   END;
the format i required is:
department  no is10
employee first name isCLARK
employee first name isKING
employee first name isMILLER
department  no is20
employee first name isJONES
employee first name isFORD
employee first name isSMITH
employee first name isSCOTT
department  no is30
employee first name isWARD
employee first name isTURNER
thanks..

Hi,
What's wrong with your current code?  The only thing wrong is that it displays the department before every row (not just the first row in each department) and the line of hyphens after every row (not just the last line in each department).  Use IF statements to display these thing only when a department changes.
How can you know when a department changes?  You could add analytic functions to the query.  ROW_NUMBER can assign  numbers 1, 2, 3, ... to the rows in each department, either in ascending or descending order.  The row numbered 1 in ascending order is the first row in its department, and the row numbered 1 in descending order is the last row.
Instead of using analytic functions, you can create a local variable the your code, that remembers the last department.  If the current depatment is deifferent from the last department, then you need a line of hyphens, and a new department header.  You'' always need an additional department header before the very first row, and a row of hyphens after the very last row, too.
Either way, give it a try.  If you get stuck, post your revised code.
You could get the results you want using GROUP BY GROUPING SETS, without using PL/SQL at all, but it's more complicated and harder to maintain.

Similar Messages

  • Building report from PL/SQL cursor

    Hello,
    is there any way to build APEX report using just PL/SQL cursor?
    I don't have grant to SELECT from views or tables, but I can use some functions returning row types and cursors. I know I can use them to build table from scratch with htp.p etc., but it’s not very nice. I want to do it using APEX reporting with filtering and pagination functionality.
    Is it possible?
    Regards,
    Przemek

    Apologies for the delay, I was out of the office.
    Below is a package serving as the basis for creating a view based on a pipelined function. The package is just a skeleton and will not compile in its current form, you will need to go through it filling in the blanks as described by the comments.
    If you want some control over what rows are returned by the view from a larger result set, use the set_parameters function in the WHERE clause, E.G.:
    select * from really_big_complicated_slow_view where 1 = view_pkg.set_parameters(something_that_reduces_the_view_result_set_size);
    Or, a more concrete example:
    select result_text from view_to_convert_to_csv where 1 = view_pkg.set_parameters(pi_table => 'my_table', pi_where = 'whatever');
    In the spirit of full disclosure, I got the idea for using the "set_parameters" function in the view WHERE clause from a post or blog somewhere a couple of years ago but have lost track of who actually deserves the credit for the good idea.
    -Tom
    create or replace package demo_vw as
    -- Package to serve as the basis for a view based on a function
    -- Customize this record so that it represents a row from this view...
    type row_type is record (
    -- record fields here
    type table_type is table of row_type;
    -- This function is used in the DDL to define the view, for example:
    -- create or replace view my_view (col1, col2, ..., colN) as
    -- select * from table(my_view_vw.get_view);
    function get_view
    return table_type
    pipelined;
    -- Customize this function header to accept the parameters for this view, if
    -- any. If this view does not require any parameters, the set_parameters
    -- function may be deleted.
    -- This function should always return 1 and is called as follows
    -- select <whatever>
    -- from my_view
    -- where 1 = my_view_vw.set_parameters(p1, p2, p3, ..., pN);
    function set_parameters (pi_whatever1 in whatever,
    pi_whateverN in whatever)
    return number;
    end demo_vw;
    show error package demo_vw
    create or replace package body demo_vw as
    -- Customize this list of private global variables to match the parameters
    -- required by the view. These variables are set, reset, and validated by
    -- set_parameters, reset_parameters, and valid_parameters respectively...
    g_var1 whatever;
    g_varN whatever;
    function set_parameters (pi_whatever1 in whatever,
    pi_whateverN in whatever)
    return number
    is
    -- Customize this function header to accept the parameters for this view, if
    -- any. If this view does not require any parameters, the set_parameters
    -- function may be deleted.
    -- This function should always return 1 and is called as follows
    -- select col1, col2, ..., colN
    -- from my_view
    -- where 1 = my_view_vw.set_parameters(p1, p2, p3, ..., pN);
    begin
    g_var1 := pi_whatever1;
    g_varN := pi_whateverN;
    return 1;
    end set_parameters;
    function valid_parameters
    return boolean
    is
    -- Customize...
    -- Assumes that set_parameters has been called to set the value of the view
    -- parameters.
    l_valid boolean := true;
    begin
    return l_valid;
    end valid_parameters;
    procedure reset_parameters
    is
    -- Customize...
    -- This is called at the end of the get_view function to reset the view
    -- parameters for the next caller.
    begin
    g_var1 := null;
    g_varN := null;
    end reset_parameters;
    function get_view
    return table_type
    pipelined
    is
    -- build and return each row for the view...
    l_row row_type;
    begin
    if valid_parameters then
    -- do your process to populate the l_row variable here...
    pipe row (l_row);
    end if;
    reset_parameters;
    exception
    when others then
    reset_parameters;
    raise;
    end get_view;
    end demo_vw;
    show error package body demo_vw
    create or replace view demo
    as
    select * from table(demo_vw.get_view);

  • Implicit PL/SQL cursors remain open, causing ORA-01000 (Client 9.2.0.1)

    Hello,
    since migrating our system from Oracle Client 9.0.X to 9.2.0.1 (Windows XP), i am encountering troubles when calling a stored procedure from a Cobol-Program:
    after a while i run into a 'Maximum open cursors exceeded'-message (ORA-01000)
    The stored procedure returns a cursor (ref_cursor)
    When Executing the stored procedure, there are actually 2 cursors involved, in fact the stored PL/SQL procedure implicitely opens a child-cursor when doing a select within the PL/SQL.
    After fetching the result and closing the cursor in my cobol-program, it correctly closes the cursor associated with the stored-procedure, but it does not close the cursor that was implicitely opened by oracle.
    After a while i am running into a Maximum open cursors message, because those cursors have not properly been closed.
    Here's a simple PL/SQL package that illustrates the problem:
    create or replace package scott.SCOTTS_PACKAGE is
    type ref_cursor IS REF CURSOR;
    function GET_EMP(EMP_IN CHAR) return ref_cursor;
    end SCOTTS_PACKAGE;
    create or replace package body scott.SCOTTS_PACKAGE is
    -- Function and procedure implementations
    function GET_EMP(EMP_IN CHAR) return ref_cursor is
    MyCurs ref_cursor;
    begin
    OPEN MyCurs FOR
    SELECT EMPNO ,
    ENAME ,
    JOB
    FROM SCOTT.EMP
    WHERE ENAME = EMP_IN;
    return(MyCurs);
    end;
    end SCOTTS_PACKAGE;
    Here are some exerpts from my cobol program:
    (The program iterates 100x through the section that executes the PL/SQL. After each iteration an additional open cursor remains in the database)
    003800 EXEC SQL BEGIN DECLARE SECTION END-EXEC.
    003900*
    004000 01 SQL-USERNAME PIC X(16) VARYING.
    004100 01 SQL-PASSWD PIC X(16) VARYING.
    004200 01 SQL-DBNAME PIC X(64) VARYING.
    004300 01 ORACLE.
    004700 02 ORA-CUR-EMP SQL-CURSOR.
    01 EMPREC.
    02 EMPREC-EMPNO PIC X(4).
    02 EMPREC-ENAME PIC X(10).
    02 EMPREC-JOB PIC X(9).
    005400 EXEC SQL END DECLARE SECTION END-EXEC.
    018400 PROCEDURE DIVISION.
    CONTINUE.
    018700 EXEC SQL
    018800 WHENEVER SQLERROR DO PERFORM SQL-ERROR
    018900 END-EXEC.
    019000*
    CONTINUE.
    019100 EXEC SQL
    019200 WHENEVER NOT FOUND DO PERFORM SQL-NOT-FOUND
    019300 END-EXEC.
    022400 EXEC SQL
    022500 ALLOCATE :ORA-CUR-EMP
    022600 END-EXEC
    PERFORM VARYING I FROM 1 BY 1 UNTIL I > 100
    ACCEPT DUMMY FROM TER
    IF DUMMY = "E"
    MOVE 100 TO I
    END-IF
    PERFORM GET-EMP
    ADD 1 TO I
    END-PERFORM
    119300 GET-EMP SECTION.
    119400************************
    119500 GAM0.
    MOVE SPACES TO EMPREC-EMPNO EMPREC-JOB
    MOVE "SMITH" TO EMPREC-ENAME
    120200 EXEC SQL AT SSSI EXECUTE
    120300 BEGIN
    120400 :ORA-CUR-EMP:=
    120500 SCOTT.SCOTTS_PACKAGE.GET_EMP(:EMPREC-ENAME );
    120900
    END;
    121000 END-EXEC
    121200 IF DB-ERR-CODE NOT = HIGH-VALUE
    121300 DISPLAY "CCSIFSO:GET-AUTRE-MATR:APPEL PERS... OK"
    121400 EXEC SQL
    121500 FETCH :ORA-CUR-EMP
    121600 INTO
    121700 :EMPREC-EMPNO,
    121800 :EMPREC-ENAME,
    121900 :EMPREC-JOB
    122400 END-EXEC
    122500 END-IF
    122600*
    122700 IF DB-ERR-CODE NOT = HIGH-VALUE
    122800 DISPLAY "CCSIFSO:GET-AUTRE-MATR:APPEL FETCH.. OK"
    123000 ELSE
    123100 MOVE LOW-VALUE TO DB-ERR-CODE
    123200 END-IF
    123300 EXEC SQL
    123400 CLOSE :ORA-CUR-EMP
    123500 END-EXEC
    123600 GA-EX.
    123700 EXIT.
    124000 SQL-NOT-FOUND SECTION.
    124100*----------------------
    124200 NF0.
    124300 DISPLAY "CCSIFSO:SQL-NOT-FOUND SECTION."
    124400 MOVE HIGH-VALUE TO DB-ERR-CODE.
    124500 NF-EX.
    124600 EXIT.
    124700*
    124800 SQL-ERROR SECTION.
    124900*-----------------
    125000 ER0.
    125200 EXEC SQL
    125300 WHENEVER SQLERROR CONTINUE
    125400 END-EXEC
    125700 MOVE HIGH-VALUE TO DB-ERR-CODE
    125800*
    126100 DISPLAY "ORACLE ERROR DETECTED: " SQLCODE UPON TER
    126200 DISPLAY SQLERRMC UPON TER
    126300*
    126400 EXEC SQL AT SSSI
    126500 ROLLBACK WORK
    126600 RELEASE
    126700 END-EXEC
    126800 DISPLAY "----------------------------" UPON TER
    126900 DISPLAY " ! ROLLBACK ET DISCONNECT ! " UPON TER
    127000 DISPLAY "----------------------------" UPON TER
    127200 CALL "PPTERMJ".
    127400 ER-EX.
    127500 EXIT.
    Finally here's an exerpt from V$OPEN_CURSOR, after a few iterations:
    1 begin :b1 := SCOTT . SCOTTS_PACKAGE . GET_EMP (:b2 ) ; END ;
    2 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    3 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    4 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    5 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    6 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    7 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    8 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    9 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    10 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    11 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    As you see, there is only 1 cursor starting with 'begin ... '
    but there are 10 implicit cursors 'SELECT EMPNO, ... ' that have not been properly closed, nor reused by ORACLE.
    In our old configuration (ORACLE CLient 9.0.X), you would only see:
    1 begin :b1 := SCOTT . SCOTTS_PACKAGE . GET_EMP (:b2 ) ; END ;
    2 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    meaning all the other cursors have properly been closed.
    As a conclusion: the program correctly closes the implicit cursors when using a 9.0 Client, wheras the implicit cursors remain open on Client 9.2.0.1 (Windows XP)
    The underlying database can be either 8.i or 9, the problem remains the same.
    Finally here's a small Delphi code, using ODAC-components, that somewhat illustrates the same problem:
    procedure TForm1.ExecProcClick(Sender: TObject);
    var I: INTEGER ;
    begin
    FOR I := 1 TO 5 DO
    BEGIN
    SP1.StoredProcName:='SCOTT.SCOTTS_PACKAGE.GET_EMP';
    SP1.Prepare;
    SP1.ParamByName('EMP_IN').AsString := 'SMITH';
    SP1.ExecProc;
    SP1.Next;
    SP1.Close;
    SP1.UnPrepare;
    END;
    end;
    After each call to 'PREPARE', an additional implicit cursor remains open on the database. (using Oracle Client 9.2.0.1)
    On our old system (Oracle Client 9.0 or 8.X), the same program would not generate accumulating open cursors on the database
    Any suggestions would be welcome,
    Claude

    Cobol.. been many years since I last even saw some Cobol source code. Invokes all kinds of memories. :-)
    Since you found the patch, the advice is superfluous, but works. Close the cursor at the PL/SQL side, e.g.
    create or replace procedure CloseRefCursor( cRefCursor TYPELIB.TRefCursor ) is
    begin
      close cRefCursor;
    exception when OTHERS then
      -- if the cursor is already gone, not a problem
      NULL;
    end;In Delphi for example, one can subclass the class used for ref cursor calls and add a call to the above PL/SQL proc in the destructor. Or add create a standard Cobol close ref cursor section that does similar.

  • Error while executing Procedure - ORA-06511: PL/SQL: cursor already open

    I have successfully compiled the following procedure but when I execute it, following error occurs, please adv.
    Thanks and Regards,
    Luqman
    create or replace
    procedure TESTKIBOR
    (contno in varchar)
    AS
    BEGIN
    DECLARE cursor c1 is
    SELECT * FROM KIBOR_SCHEDULE
    WHERE CN=contno;
    begin
    OPEN C1;
    FOR line IN c1 LOOP
    update kibor_schedule
    set lincome=line.Lincome,
    expo=line.eXPO,
    pport=line.pPORT
    where cn=line.cn
    and rno=line.rno;
    END LOOP;
    COMMIT;
    close c1;
    END;
    END TESTKIBOR;
    ERROR at line 1:
    ORA-06511: PL/SQL: cursor already open
    ORA-06512: at "MKTG.TESTKIBOR", line 6
    ORA-06512: at "MKTG.TESTKIBOR", line 10
    ORA-06512: at line 1

    Hi,
    CREATE OR REPLACE PROCEDURE Testkibor
         (contno  IN VARCHAR)
    AS
    BEGIN
      DECLARE
        CURSOR c1 IS
          SELECT *
          FROM   kibor_schedule
          WHERE  cn = contno;
      BEGIN
    --//    OPEN c1; --no need to open if using for loop
        FOR line IN c1 LOOP
          UPDATE kibor_schedule
          SET    lincome = line.lincome,
                 expo = line.expo,
                 pport = line.pport
          WHERE  cn = line.cn
                 AND rno = line.rno;
        END LOOP;
        COMMIT;
    --//     CLOSE c1; -- no need for loop  does it for you
      END;
    END testkibor;SS

  • Need help on Dynamic SQL Cursor in Forms

    Hi All,
    I am trying to execute Dynamic SQL Cursor in forms using EXEC_SQL built in.
    I have a cursor for example:
    'select * from supplier where supplier = '||p_supplier||' and processing_order = '||p_order
    My code is
    cur_num := Exec_SQL.Open_cursor;
    sql_order := 'select * from supplier where supplier = '||p_supplier||' and processing_order = '||p_order;
    EXEC_SQL.PARSE(cursor_number, sql_order);
      EXEC_SQL.DEFINE_COLUMN(cur_num ,1,ln_Supp_Id);
      EXEC_SQL.DEFINE_COLUMN(cur_num ,2,ls_Suppl_Name,30);
    EXEC_SQL.DEFINE_COLUMN(cur_num ,24,ls_exchange,20);
      sql_count := EXEC_SQL.EXECUTE(cur_num );
      While EXEC_SQL.FETCH_ROWS(cur_num ) > 0 Loop
            EXEC_SQL.COLUMN_VALUE(cur_num ,1,ln_Supp_Id);
            EXEC_SQL.COLUMN_VALUE(cur_num ,2,ls_Suppl_Name);
            EXEC_SQL.COLUMN_VALUE(cur_num ,24,ls_exchange);
    End Loop;
    EXEC_SQL.CLOSE_CURSOR(cur_num );
    In this case I have to write 24 Define Columns and 24 Column value. Is there any way to assign them to %rowtype at one time as I need all coulmn of the table.
    I had similar case on multiple tables.
    Please help me
    Thanks,
    Maddy

    I need this dynamic sql because p_supplier and p_order values changes at run time
    I do not understand. Is this a simplified sample or the real thing? You do know that you can pass variables to cursors:
    cursor test is
    select * from supplier where supplier = p_supplier and processing_order = p_order;
    or does e.g. p_supplier hold other parts of the query?
    cheers

  • Size of PL\SQL Cursor block

    I want to know the internal working of the PL\SQL Cursor. Lets start with a scenario.
         1) I have 3 table with 20 million records each.
         2) I am making a join out of them on a certain condition which gives me 60 million records, now I am putting them in a cursor.
    Questions :
         i) Can the Oracle PL\SQL Cursor is capable of holding that much records or there is any limit for it ?
         ii) If there is a limit for such block, then where can I find it and how can I set it ?
         3) If there is no such limit, then running such a query and holding all the data in the Cursor Block would degrade the performance. How Oracle handles such situations, It might be possible that Oracle only have the indexes of those records in the Cursor, but still it would be to time consuming to index 3 different table
    Kindly Inform me about this issue ....
    Thanks & regards
    - Nabil Shams

    1. Oracle PL/SQL cursor is just a handle to shared SQL area in Oracle SGA and as such does not consume an awful lot of memory (I would dare to say it consumes peanuts). What is more important it does not depend on number of rows you are going to fetch via cursor
    2. Therefore the answer to question 2 is NO
    3. Running the query could and would affect you in most unpleasnat ways if you tried to store results of the query in your process memory (PGA/UGA), or more specifically if you created PL/SQL indexed by table and tried to pack all 60000000 rows into it.
    If you fetch rows one by one, process the row, throw it away - then no problem... but what do you need to do it for?

  • Need a column based off a PL/SQL cursor, how to do this?

    Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production
    With the Real Application Testing option
    JServer Release 9.2.0.8.0 - Production
    Report Builder 10.1.2.2.0
    ORACLE Server Release 10.1.0.5.0
    Oracle Procedure Builder 10.1.2.2.0
    Oracle ORACLE PL/SQL V10.1.0.5.0 - Production
    Oracle CORE     10.1.0.5.0     Production
    Hi,
    I am trying to create a fairly basic report but in the initial data model query, I have one column that is built based off of a PL/SQL cursor. How do I add this into my report? I have tried to create a function under Program Units and reference the function in my select statement for the data model however it keeps saying it is an invalid identifier, and I assume its looking in our database and not the function I created inside the report.
    This is what it looks like:
    SELECT   a.id,
             b.name,
             F_GET_GENERIC_NAME(b.code) "Generic Name",
             c.strength...and the function i want it to use in my report:
    FUNCTION F_GET_GENERIC_NAME (in_code varchar2) RETURN VARCHAR2 IS
    BEGIN
    DECLARE
    generic_name table.column%TYPE;
    CURSOR cs_get_generic_name IS
    SELECT /*+ USE_HASH (AR) */ desc
    FROM  a_ref AR, ai_ic AC    
    WHERE AC.code = in_code
    AND   AC.code = AR.code
    ORDER BY sort_nbr;
    BEGIN
           generic_name := '';
              FOR v_get_generic_name IN cs_get_generic_name
              LOOP
                 generic_name := generic_name || RTRIM(v_get_generic_name.desc)
                                     || '/' || ' ';
              END LOOP;
              generic_name := SUBSTR(generic_name, 1,(NVL(LENGTH(generic_name), 0) - 2));
    RETURN generic_name;
    END;
    END;
        Any suggestions? Should I just create the function in the database?

    I am trying to do it through a formula column but am encountering the following problem.
    I've created a formula column in my data model where I want the column to be (inside the group).
    Inside the PL/SQL for the column I reference the function that I had previously created with the following:
    function CF_Generic_nameFormula return Char is
    begin
         F_GET_GENERIC_NAME(:code);
    end;However it won't let me compile, giving the error that "F_GET_GENERIC_NAME is not a procedure or is undefined." Is there something else that I am missing?
    EDIT: Nevermind, i missed something simple like putting a return in front of the function call.
    Edited by: a small rabbit on Nov 3, 2009 10:43 AM
    Edited by: a small rabbit on Nov 3, 2009 10:44 AM

  • How to see pl/sql cursor in v$sql

    Hi All,
    I am trying to find how many child cursor will be created for select * into employee_rec from employees where employee_id = i however I couldn't find anything?
    Do I have to use execute immediate?
    Can't I measure PL/SQL cursors?
    set serveroutput on;
    declare
         employee_rec employees%rowtype;
    begin
         for i in 100..110
         loop
                select * into employee_rec from employees where employee_id = i;
                dbms_output.put_line(employee_rec.first_name);
         end loop;
    end;
    select sql_text, sql_ıd, versıon_count, hash_value from v$sqlarea where sql_text like 'select * into employee_rec from employees where employee_id%';
    <<No row returns>>
    select sql_text, sql_id, child_number, hash_value, plan_hash_value from v$sql where sql_text like 'select * into employee_rec from employees where employee_id%';
    <<No row returns>>
    Thanks in advance

    For example, I changed the code like the following
    I just would like the see the cursor (select * from employees where employee_id = emp_id;) you know what I mean?
    set serveroutput on;
    declare
    cursor my_c(emp_id number) is
    select * from employees where employee_id = emp_id;
    begin
         for i in 100..110
         loop
                for rec in my_c(i)
                loop
                  dbms_output.put_line(rec.first_name);
                end loop;
         end loop;
    end;
    Thanks

  • At what point is PL/SQL cursor data retrieved?

    Hi
    This may sound like a silly question but since I am not entirely sure, I thought I'd ask.
    In Oracle PL/SQL, do you know at what stage the query in a cursor is actually executed?
    Is it at the DECLARE stage or when you first OPEN / LOOP on it?
    I suspect upon the OPEN or the LOOP.
    I.e. if I had a cursor declared but did not loop (using FOR .. LOOP) through it for some hours, would the query results be as at the time of declare or as at the time of the OPEN / FOR...LOOP?
    E.g.
    CURSOR invoices
      IS
        SELECT invoice_number
        FROM unpaid_invoices
        WHERE due_date < TRUNC (SYSDATE)
    BEGIN
    -- Some time consuming processing that will take an hour
    -- Start Loop through cursor of invoices.
      <<overdue_invoices>>
      FOR inv IN invoices LOOP
    -- Some processing on the invoice
      END LOOP overdue_invoices;
    END;Would the cursor details for invoices be as at the CURSOR declaration or when the FOR inv... is reached?
    Thanks
    Martin

    When you use a for loop like that it implicitly opens the cursor at the start and closes it at the end of the loop.
    But the SQL query in that cursor is actually "run" when the first implicit or explicit fetch is issued, and retrieves new rows for every subsequent fetch.
    Of course, before rows can be retrieved there needs to be several other tasks.
    There's a good description of the steps of SQL processing in this part of the documentation.
    http://download.oracle.com/docs/cd/E11882_01/appdev.112/e10471/adfns_sqlproc.htm
    PL/SQL implicitly declares a cursor for all SQL data manipulation statements, including queries that return only one row. For queries that return multiple rows, you can explicitly declare a cursor to process the rows individually.
    A cursor is a handle to a specific private SQL area. In other words, a cursor can be thought of as a name for a specific private SQL area. A PL/SQL cursor variable enables the retrieval of multiple rows from a stored subprogram.Edited by: fsitja on Dec 15, 2009 1:03 AM

  • PL/SQL cursors vs. SQL*plus Select statement

    Hi folks, hope you're doing well,
    Here is a question that kept me wondering:
    Why would I use cursors when i can achieve the same thing with a SQL+ Select statement which is much easier to formulate than a cursor (e.g. you need no declaration, loops etc)?.
    Thanks so much,
    -a

    There is no such thing as a SQL*Plus SELECT statement. The SELECT command is part of the SQL Language - not part of the SQL*Plus (very limited small vocabulary) macro language.
    All SQL SELECTs (from client languages) winds up in the SQL Engine as SQL cursors. A SQL Cursor is basically the:
    - SQL source code
    - SQL "compiled" code (instructions on how to fetch the rows)
    On the client side, client cursors (not to be confused with SQL cursors) are used. A client cursor is created in the client language when it makes SQL calls via the database client driver (called the OCI/Oracle Call Interface for Oracle clients).
    Typically this is what a client does. It makes a connection to the database and gets a database handler in return. The database handler is the "communication channel" from the client to the db. In Oracle, the database handler in the client refers to the Oracle session (for that client) on db server.
    A SQL statement (source code) is used by the client. This can be a SELECT statement you type in at the SQL*Plus command line. It can be a SELECT statement for the PL/SQL cursor command in a stored procedure.
    The client creates a SQL handle for this SQL statement, by calling the Oracle client driver. Note that this SQL handle is a client handle - a client cursor for that SQL statement.
    E.g.
    a) sqlHandle = CreateSQL( databaseHandle, 'SELECT ... FROM ...')
    b) sqlHandle.Parse
    c) sqlHandle.Execute
    After the SQL handle (client cursor) has been executed, the client can fetch rows from it.
    This is what SQL*Plus does automatically for you, without you having to write the code to do it. SQL*Plus CONNECT command create a database connection handle. You enter a SELECT statement and SQL*Plus creates a SQL handle (client cursor), executes it, fetches from it, displays the rows, and closes the SQL handle when done.
    The same applies to PL/SQL. You can use a SELECT statement just like that in PL/SQL. E.g.
    declare
      i integer;
    begin
      select count(*) into i from emp where deptid = 123;
    end;This is called an implicit cursor. PL/SQL creates (just like SQL*Plus) an implicit client cursor. It creates and disposes of that client SQL handle for you - you do not need to do it.
    Or, you can create an explicit cursor. E.g. declare
      cursor c is select count(*) from emp where deptid = 123;
      i integer;
    begin
      open c;
      fetch c into i;
      close c;
    end;The question as to when to use implicit (client) cursors versus explicit (client) cursors depends on your requirements. Do you need to cycle through the results of the SQL? Etc.
    And keep in mind that in either case, the SQL Engine creates a SQL cursor anyway on its side.

  • CR+LF Code at the end of each record selected in sql cursor

    i am selecting some data records in a sql cursor and writing it into a file using UTL_FILE.puT in a plsql procedure.
    at the end of select statement if i add ||chr(13||chr(10) iam getting CR+CR+LF code
    if i add only || chr(10) i am getting LF code.
    What i need is only CR+LF code. Kindly help to use any other commands.
    Thanks,
    Shivaji.
    Edited by: Shivaji M on Apr 22, 2010 12:11 AM
    Edited by: Shivaji M on Apr 22, 2010 12:36 AM

    It's in the book!
    "PUT_LINE terminates the line with the platform-specific line terminator character or characters."
    http://download.oracle.com/docs/cd/E11882_01/appdev.112/e10577/u_file.htm#i997640

  • Returning SQL cursor from Stored Procedure

    Hi,
    I have a query regarding returning sql cursor from stored procedure to java in oracle 11g.
    I want to query some data ex: my query returns A, B, C. Also, now I want to query some other data ex: D, E, F. Now I want to return this data as an sql cursor as a single row . Example: A,B,C,D,E,F. Is it possible to return/create a cursor in stored procedure?
    assume both query returns equal number of rows.. however both are not related to each other..

    RP wrote:
    Hi,
    I have a query regarding returning sql cursor from stored procedure to java in oracle 11g.
    I want to query some data ex: my query returns A, B, C. Also, now I want to query some other data ex: D, E, F. Now I want to return this data as an sql cursor as a single row . Example: A,B,C,D,E,F. Is it possible to return/create a cursor in stored procedure?
    assume both query returns equal number of rows.. however both are not related to each other..It sounds like what you need is a ref cursor.
    First thing to remember though is that cursors do not hold any data (see: {thread:id=886365})
    In it's simplest form you would be creating a procedure along these lines...
    SQL> create or replace procedure get_data(p_sql in varchar2, p_rc out sys_refcursor) is
      2  begin
      3    open p_rc for p_sql;
      4  end;
      5  /
    Procedure created.
    SQL> var rc refcursor;
    SQL> exec get_data('select empno, ename, deptno from emp', :rc);
    PL/SQL procedure successfully completed.
    SQL> print rc;
         EMPNO ENAME          DEPTNO
          7369 SMITH              20
          7499 ALLEN              30
          7521 WARD               30
          7566 JONES              20
          7654 MARTIN             30
          7698 BLAKE              30
          7782 CLARK              10
          7788 SCOTT              20
          7839 KING               10
          7844 TURNER             30
          7876 ADAMS              20
          7900 JAMES              30
          7902 FORD               20
          7934 MILLER             10
    14 rows selected.
    SQL> exec get_data('select deptno, dname from dept', :rc);
    PL/SQL procedure successfully completed.
    SQL> print rc
        DEPTNO DNAME
            10 ACCOUNTING
            20 RESEARCH
            30 SALES
            40 OPERATIONS
            50 IT SUPPORTWhich takes an SQL statement (as you said that both your queries were unrelated), and returns a ref cursor, and then your Java code would fetch the data using that cursor.
    Now, as for getting your rows to columns and combining two queries that do that... something along these lines...
    SQL> select * from x;
    C
    A
    B
    C
    SQL> select * from y;
    C
    D
    E
    F
    SQL> ed
    Wrote file afiedt.buf
      1  select x.col1, x.col2, x.col3
      2        ,y.col1 as col4
      3        ,y.col2 as col5
      4        ,y.col3 as col6
      5  from (
      6        select max(decode(rn,1,col1)) as col1
      7              ,max(decode(rn,2,col1)) as col2
      8              ,max(decode(rn,3,col1)) as col3
      9        from (select col1, rownum rn from (select * from x order by col1))
    10       ) x
    11  cross join
    12       (
    13        select max(decode(rn,1,col1)) as col1
    14              ,max(decode(rn,2,col1)) as col2
    15              ,max(decode(rn,3,col1)) as col3
    16        from (select col1, rownum rn from (select * from y order by col1))
    17*      ) y
    SQL> /
    C C C C C C
    A B C D E F... will do what you ask. For further information about turning rows to columns read the FAQ: {message:id=9360005}

  • SQL Cursors HELP  ASAP

    I need somebody to help me with sql cursors, in JSP.
    This is my peace of code what is wrong with it?
              Statement stmt = myConn.createStatement();
              stmt.executeQuery("BEGIN WORK");
              stmt.executeQuery("DECLARE item_cursor CURSOR FOR SELECT user_name FROM admin_info");
              stmt.executeQuery("FETCH 10 FROM item_cursor");
              ResultSet rs = stmt.getResultSet();
              while(rs.next()){
                   if(rs.getString(1) != null){
                        user_name = rs.getString(1).trim();
    %><P><%= user_name %></P><%
              stmt.executeQuery("CLOSE item_cursor");
              stmt.executeQuery("COMMIT WORK");
    and this is the error that a get: No results where returned by the query
    Please help anybody
    thanx guys

    If you are using ORACLE drivers and classes.
    This sample program shows Oracle JDBC REF CURSOR functionality, creating a PL/SQL package that includes a stored function that returns a REF CURSOR type. The sample retrieves the REF CURSOR into a result set object.
    * This sample shows how to call a PL/SQL function that opens
    * a cursor and get the cursor back as a Java ResultSet.
    import java.sql.*;
    import java.io.*;
    import oracle.jdbc.driver.*;
    class RefCursorExample
    public static void main (String args [])
    throws SQLException
    // Load the driver
    DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
    // Connect to the database
    // You can put a database name after the @ sign in the connection URL.
    Connection conn =
    DriverManager.getConnection ("jdbc:oracle:oci8:@", "scott", "tiger");
    // Create the stored procedure
    init (conn);
    // Prepare a PL/SQL call
    CallableStatement call =
    conn.prepareCall ("{ ? = call java_refcursor.job_listing (?)}");
    // Find out all the SALES person
    call.registerOutParameter (1, OracleTypes.CURSOR);
    call.setString (2, "SALESMAN");
    call.execute ();
    ResultSet rset = (ResultSet)call.getObject (1);
    // Dump the cursor
    while (rset.next ())
    System.out.println (rset.getString ("ENAME"));
    // Close all the resources
    rset.close();
    call.close();
    conn.close();
    // Utility function to create the stored procedure
    static void init (Connection conn)
    throws SQLException
    Statement stmt = conn.createStatement ();
    stmt.execute ("create or replace package java_refcursor as " +
    " type myrctype is ref cursor return EMP%ROWTYPE; " +
    " function job_listing (j varchar2) return myrctype; " +
    "end java_refcursor;");
    stmt.execute ("create or replace package body java_refcursor as " +
    " function job_listing (j varchar2) return myrctype is " +
    " rc myrctype; " +
    " begin " +
    " open rc for select * from emp where job = j; " +
    " return rc; " +
    " end; " +
    "end java_refcursor;");
    stmt.close();

  • Understanding SQL cursor attributes

    I was trying to understand the use of SQL cursor attributes.So i chose sql%notfound attribute to be used with an exception in the below example.
    create or replace procedure checkExcp
    is
    v_empName varchar2(30);
    exp_no_row_found exception;
    errorMessage varchar2(500);
    begin
    select ename into v_empName from emp where empno = '8000';
    if sql%notfound then
         raise exp_no_row_found ;
    end if;
    exception
    when exp_no_row_found
    then
      errorMessage := 'Error occured while executing updateInventoryTotalsInDB function: ';
    end;When i debugged this proc i realized that the
    if sql%notfound then
         raise exp_no_row_found ;bit of the code(and the custom exception exp_no_row_found) is useless. Because when no rows are returned by the query
    select ename into v_empName from emp where empno = '8000';it straightaway goes to the exception block bypassing the 'if sql%notfound....' bit. So when is a SQL cursor attribute like sql%notfound useful?

    But i want to add specific error messages to each
    SELECT...INTO statements. So a single,common
    NO_DATA_FOUND exception would mask these specific
    errors.Then don't make it a single, common exception block. Have specific execution blocks with their own exception block for each different way you want to handle the exception e.g.
    BEGIN
      BEGIN
        SELECT mydata INTO myvar FROM mytable;
      EXCEPTION
        WHEN NO_DATA_FOUND THEN
          myvar := 'No data for myvar';
      END;
      BEGIN
        SELECT myotherdata INTO myvar2 FROM mytable;
      EXCEPTION
        WHEN NO_DATA_FOUND THEN
          myvar2 := 'No data for myvar2';
      END;
    END;Nested execution blocks are your friend when you want to handle exceptions for specific areas.

  • Help with "ORA-06511: PL/SQL: cursor already open"

    I've tried numerous variations on this piece of code and I always get the same result. I'm sure this is painfully obvious to an experienced PL/SQL person.
    Any help will be appreciated!
    Thank You!
    1 DECLARE
    2 CURSOR EMP_CURSOR IS SELECT last_name from employees;
    3 current_last_name varchar2(25);
    4 BEGIN
    5 IF EMP_CURSOR%ISOPEN
    6 THEN
    7 dbms_output.put_line ('cursor is already open');
    8 close EMP_CURSOR;
    9 END IF;
    10 dbms_output.put_line ('opening cursor');
    11 OPEN EMP_CURSOR;
    12 FOR item in EMP_CURSOR LOOP
    13 FETCH EMP_CURSOR INTO current_last_name;
    14 EXIT WHEN EMP_CURSOR%NOTFOUND;
    15 dbms_output.put_line (item.last_name);
    16 END LOOP;
    17 CLOSE EMP_CURSOR;
    18* END;
    19 /
    DECLARE
    ERROR at line 1:
    ORA-06511: PL/SQL: cursor already open
    ORA-06512: at line 2
    ORA-06512: at line 12

    Mathieu,
    Log in as anotherSchema and grant select on 'IDsTable' to the current user.
    SQL> r
      1  create or replace function f1(theID varchar2) return mytype pipelined is
      2  out varchar2(30);
      3  cursor myCursor (x varchar2) is select * from scott.emp where job=x;
      4  begin
      5  for rec in myCursor(theID) loop
      6  pipe row(rec.ename);
      7  end loop;
      8  return;
      9* end;
    Warning: Function created with compilation errors.
    SQL> show errors
    Errors for FUNCTION F1:
    LINE/COL ERROR
    3/33     PL/SQL: SQL Statement ignored
    3/53     PL/SQL: ORA-00942: table or view does not exist
    6/1      PL/SQL: Statement ignored
    6/10     PLS-00364: loop index variable 'REC' use is invalid
    SQL> connect scott
    Enter password: *****
    Connected.
    SQL> grant select on emp to testuser;
    Grant succeeded.
    SQL> connect testuser
    Enter password: ****
    Connected.
    SQL> create or replace function f1(theID varchar2) return mytype pipelined is
      2  out varchar2(30);
      3  cursor myCursor (x varchar2) is select * from scott.emp where job=x;
      4  begin
      5  for rec in myCursor(theID) loop
      6  pipe row(rec.ename);
      7  end loop;
      8  return;
      9  end;
    10  /
    Function created.
    SQL> disconnect
    Disconnected from Oracle9i Enterprise Edition Release 9.2.0.3.0 - 64bit Production
    With the Partitioning option
    JServer Release 9.2.0.3.0 - Production
    SQL>

  • T-SQL: Cursor is not advancing to next record

    SQL Version:  2008 R2
    Problem:  I have the code below which uses a cursor.  The cursor keeps returning the first record and does not advance to the next record in the cursor.  It appears as if the Fetch Next is not being recognized.  The Select
    Statement in the cursor declaration returns two records which is the result set I expect to be contained in the cursor record set.
    ...bob sutor
    SQL CODE:
    DECLARE
      @ProcessGroupID nchar(4)
     , @RemoveAuditUser nchar(128)
    DECLARE CertGroupCursor CURSOR FOR
     SELECT DISTINCT CertGroups.GroupCode, CertGroups.RemoveAuditUser
         --, UserControl.ProcessGroupID, UserControl.VPUserName
     FROM udCertGroups AS CertGroups
      LEFT JOIN udAuditUsers AS UserControl
      ON CertGroups.GroupCode = UserControl.ProcessGroupID
     WHERE CertGroups.GroupCode = UserControl.ProcessGroupID
      AND CertGroups.RemoveAuditUser = UserControl.VPUserName
    OPEN CertGroupCursor
     FETCH NEXT FROM CertGroupCursor INTO @ProcessGroupID, @RemoveAuditUser
     WHILE @@FETCH_STATUS = 0
     Print @ProcessGroupID + '-' + @RemoveAuditUser
     DELETE FROM udAuditUsers
      WHERE ProcessGroupID = @ProcessGroupID
       AND VPUserName = @RemoveAuditUser
     FETCH NEXT FROM CertGroupCursor INTO @ProcessGroupID, @RemoveAuditUser
    CLOSE CertGroupCursor
    DEALLOCATE CertGroupCursor
    Bob Sutor

    The real question is how to get rid of this mess. Think about the local “@remove_audit_user” as a variable; it's name is a verb, not a noun! and the NVARCHAR(n) lets you use Chinese Unicode. Why? In ISO-11179 rules , “remove_” is a called a role, and the
    audit user would be the attribute with the attribute property “_user” in a valid data model. Where is the table that models “audit_users”? It has to be here by definition. 
    One of the first rules of data modeling is that a data element has one and only one name. This is a results of the Law of Identity in Logic (A is A: to be is to be something in particular, to be nothing in particular or many things in general is to be nothing
    at all). 
    So how did “G.remove_audit_user = U.vp_user_name” occur??  ANSWER: lack of a design!
    Your “G.group_code = U.process_group_id” is wrong. An identifier is not a code! TOTALLY DIFFERENT type of data elements! Do you have a postal code or a postal id? Blood_type or blood_id?  Etc.? Have you ever read a book on basic data modeling? 
    The purpose of PRINT is debugging and not output. We had  joke in the ANSI X3H2 Committee that SQL means “scarcely Qualified as a Language” because there is no I/O. PRINT will screw up performance in so many ways. 
    In a properly designed schema, we seldom use SELECT DISTINCT; we have keys and a valid schema that does not produce redundant duplicate rows. It might be valid, but after 30+ years of SQL, I would bet against it. 
    Your statement would use an EXISTS() predicate to handle multiple columns and conditions. But you did not bother with DDL, as required by basic Netiquette, so here is the skeleton I can give you. 
    DELETE FROM UD_Audit_Users
     WHERE EXIST
           (SELECT *
              FROM UD_Cert_Groups AS G
             WHERE G.process_group_id = ?? 
               AND G.vp_user_name = ??;
    --CELKO-- Books in Celko Series for Morgan-Kaufmann Publishing: Analytics and OLAP in SQL / Data and Databases: Concepts in Practice Data / Measurements and Standards in SQL SQL for Smarties / SQL Programming Style / SQL Puzzles and Answers / Thinking
    in Sets / Trees and Hierarchies in SQL

Maybe you are looking for

  • Link between Project and Sales Order

    Apart from sales order can we have a link between project and customer master ?? I know that WBS element assignment can be made in sales order but i want to have link between customer master and project. I don't want any user field or text field in s

  • Sound file causes temporary freezing

    Hi all,  I am new to labview and I've faced a problem during running my code. I have a code that calls subvi which plays a sound file of type .wav using Play Sound File VI and Sound Output Clear VI. The sound file should play when some events occure,

  • Firefox won't restore all my windows in session restore.

    I pulled the plug for my PC by mistake when I was sorting something out and I had firefox running with 3 windows opened. I switched it back on and restarted firefox. The session restore tab appeared this all my windows listed and checked, but when I

  • Can't view DFSR Health Reports in IE 10 or IE11

    As a part of monitoring our DFSR infrastructure, I generate health reports on a weekly basis and have them emailed to me.  The DFSR reports require IE in order to be viewed.  On top of that, they require IE9.  While I was able to display the page in

  • How to inherit roles between root organization unit and sub units

    Hi all, I have root organization unit and sub units: ->Company >Department 1 >Department 2 >Department 3 >Department 4 >Department 5 I would like it to work like this that all people from all departments would have access to transaction ZTEST. Most o