4 Replies Latest reply: Apr 24, 2012 12:01 AM by 932466 RSS

    Passing Ref Cursor to Oracle Stored Procedure Via C#

    932466
      Hi all,
      I am new to oracle and stuck with an issue. I have three insert stored procedures for three different tables. Two of them have multiple rows to be inserted, which is currently done via iterating through each row and insert to db in C# code. My requirement is to merge these three procedures in one and instead of iterating from C# code send table rows as (ref cursor or collection) to procedure and the procedure will handle the rest.

      I read that ref cursor only works if you're data is in database as it reference the memory but in my case data is build on client side.
      I am using Oracle 11i and ASP.Net 2.0

      Can any help me on this please?

      Edited by: 929463 on Apr 23, 2012 12:38 AM
        • 1. Re: Passing Ref Cursor to Oracle Stored Procedure Via C#
          Paul  Horth
          A simple Google search would have shown you:

          http://www.dotnetforce.com/Content.aspx?t=a&n=243
          • 2. Re: Passing Ref Cursor to Oracle Stored Procedure Via C#
            BluShadow
            929463 wrote:
            Hi all,
            I am new to oracle and stuck with an issue. I have three insert stored procedures for three different tables. Two of them have multiple rows to be inserted, which is currently done via iterating through each row and insert to db in C# code. My requirement is to merge these three procedures in one and instead of iterating from C# code send table rows as (ref cursor or collection) to procedure and the procedure will handle the rest.

            I read that ref cursor only works if you're data is in database as it reference the memory but in my case data is build on client side.
            I am using Oracle 11i and ASP.Net 2.0

            Can any help me on this please?
            If the data is built on the client side then the issue is nothing to do with ref cursors. You cannot populate a ref cursor and pass that into the database as a ref cursor is a pointer to a query that is retrieving data from the database. If you just have raw client data to pass to the database to be inserted then you should use an appropriate structure (array/collection) to pass that data in and get the PL/SQL code to process that and insert it.

            {thread:id=886365}
            • 3. Re: Passing Ref Cursor to Oracle Stored Procedure Via C#
              Billy~Verreynne
              929463 wrote:

              I am new to oracle and stuck with an issue. I have three insert stored procedures for three different tables. Two of them have multiple rows to be inserted, which is currently done via iterating through each row and insert to db in C# code. My requirement is to merge these three procedures in one and instead of iterating from C# code send table rows as (ref cursor or collection) to procedure and the procedure will handle the rest.
              Why a single procedure? How is the procedure to determine the target table to insert the data into? And please - no dynamic SQL as that is 99% of the time wrong.

              A ref cursor is something that PL/SQL creates - with the purpose of passing the cursor handle to your code. This enables the actual SQL statement for that cursor to be moved from client code, into a PL/SQL stored proc. It abstracts the client from having to understand SQL, understand the data model and so on. All clients use the same PL/SQL proc and thus the same code for creating that cursor. Thus no issue of some clients getting it half right or half wrong and dealing with data inconsistencies between clients.

              The PL/SQL proc can be tuned and optimised, modified for catering for data model changes and so on. Without your client code having to be even recompiled as it is isolated against these server changes.

              For all other interaction (running PL/SQL code, doing insert/update/delete/etc SQL statements), you need to create the cursor yourself in your code.

              Also, the SQL engine only sees cursors. There are no differences between cursors. The client (e.g. PL/SQL) can call it a reference cursor, or an implicit cursor, or a DBMS_SQL cursor.. the SQL engine does not know that and does not care.

              A ref cursor is simply a special type of client interface to a SQL cursor, allowing PL/SQL to create that SQL cursor and then pass the handle of that SQL cursor to other code to consume that cursor.

              Okay, so if you want to insert data, you need in your code to create a cursor. This can be a SQL INSERT cursor - the actual insert statement. Or it can be a PL/SQL call - an anonymous PL/SQL code block that calls a stored proc that performs the insert (after applying validation and business logic).

              The cursor will have one or more bind variables. Your client will pass values for these variables and the server-side code (SQL or PL/SQL) will be executed using this as variable data.

              You can for example create a cursor as follows:
              begin
                DoFunkyInsert( :1, :2, :3 );
              end;
              {code}
              
              3 bind variables are expected. You can now in the client build an array for each of these variables, containing a 100 values each (total of a 100 rows to insert). Do a single execute of the cursor, and tell Oracle that the bind is actually a 100 element array.
              
              The complete array ships to Oracle - Oracle opens a loop and execute the cursor for each element in the array.
              
              This is called bulk binding.
              
              An alternative approach is to define the bind variable as a collection (a non-scalar value). And then code the PL/SQL procedure to open a loop and iterate through the collection/array, inserting a row per iteration.
              
              The binding itself is more complex as your code know needs to understand Oracle object types and be able to define an array/collection that is a valid Oracle non-scalar data type.
              
              The +Oracle Call Interface+ (OCI) is quite flexible in this regard. However, as you work via an abstraction layer (e.g. ADO, OleDB, ODBC, etc) your code is subject to whatever functionality this abstraction layer makes available to your code. And this is seldom includes all the power, functionality and flexibility of the (more complex) OCI itself.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
              • 4. Re: Passing Ref Cursor to Oracle Stored Procedure Via C#
                932466
                Thanks to you all for your help.
                But somehow I was unable to do it via cursor, so I switched to Types..
                I have created Custom Types in database and in .net and passing them as an object collection to my procedure.
                So, far this approach is working.

                Thanks again.