Microsoft KB Archive/239771: Difference between revisions

From BetaArchive Wiki
m (Text replacement - ">" to ">")
m (Text replacement - """ to """)
 
(One intermediate revision by the same user not shown)
Line 58: Line 58:
The resultsets created by the Microsoft ODBC Driver for Oracle version 2.0 and 2.5 using Oracle stored procedures are READ ONLY and Static. Retrieving a resultset requires the creation of an Oracle Package.<br />
The resultsets created by the Microsoft ODBC Driver for Oracle version 2.0 and 2.5 using Oracle stored procedures are READ ONLY and Static. Retrieving a resultset requires the creation of an Oracle Package.<br />
<br />
<br />
Before beginning to work with the Visual FoxPro application, an Oracle package called FoxPackage must be created. FoxPackage is taken from the Help File for Microsoft ODBC Driver for Oracle: Advanced Topics: &quot;Returning Array Parameters from Stored Procedures&quot;.<br />
Before beginning to work with the Visual FoxPro application, an Oracle package called FoxPackage must be created. FoxPackage is taken from the Help File for Microsoft ODBC Driver for Oracle: Advanced Topics: "Returning Array Parameters from Stored Procedures".<br />
<br />
<br />
'''Note''' The following code requires installation of Microsoft Data Access Components (MDAC) version 2.x or later. MDAC is included in the data components of Visual Studio 6.0 or can be downloaded from the following Web site:
'''Note''' The following code requires installation of Microsoft Data Access Components (MDAC) version 2.x or later. MDAC is included in the data components of Visual Studio 6.0 or can be downloaded from the following Web site:
Line 70: Line 70:
<li><p>Create a program file named Procs.prg using the code snippet below. This code will be used to create an Oracle package definition and package body:</p>
<li><p>Create a program file named Procs.prg using the code snippet below. This code will be used to create an Oracle package definition and package body:</p>
<pre class="codesample">*!* Step 1 Create the package definition string
<pre class="codesample">*!* Step 1 Create the package definition string
Proc_String1=&quot;CREATE OR REPLACE PACKAGE FoxPackage AS &quot; + CHR(13) + ;
Proc_String1="CREATE OR REPLACE PACKAGE FoxPackage AS " + CHR(13) + ;
   CHR(10) + ;
   CHR(10) + ;
   &quot;   TYPE t_id is TABLE of  NUMBER(5) &quot; + CHR(13) + CHR(10) + ;
   "   TYPE t_id is TABLE of  NUMBER(5) " + CHR(13) + CHR(10) + ;
   &quot;   INDEX BY BINARY_INTEGER; &quot; + CHR(13) + CHR(10) + ;
   "   INDEX BY BINARY_INTEGER; " + CHR(13) + CHR(10) + ;
   &quot;   TYPE t_Course is TABLE of VARCHAR2(10) &quot; + CHR(13) + CHR(10) + ;
   "   TYPE t_Course is TABLE of VARCHAR2(10) " + CHR(13) + CHR(10) + ;
   &quot;   INDEX BY BINARY_INTEGER; &quot; + CHR(13) + CHR(10) + ;
   "   INDEX BY BINARY_INTEGER; " + CHR(13) + CHR(10) + ;
   &quot;   TYPE t_Dept is TABLE of VARCHAR2(5) &quot; + CHR(13) + CHR(10) + ;
   "   TYPE t_Dept is TABLE of VARCHAR2(5) " + CHR(13) + CHR(10) + ;
   &quot;   INDEX BY BINARY_INTEGER; &quot; + CHR(13) + CHR(10) + ;
   "   INDEX BY BINARY_INTEGER; " + CHR(13) + CHR(10) + ;
   &quot;   TYPE t_pk1Type1 IS TABLE OF VARCHAR2(100) &quot; + CHR(13) + CHR(10) + ;
   "   TYPE t_pk1Type1 IS TABLE OF VARCHAR2(100) " + CHR(13) + CHR(10) + ;
   &quot;   INDEX BY BINARY_INTEGER; &quot; + CHR(13) + CHR(10) + ;
   "   INDEX BY BINARY_INTEGER; " + CHR(13) + CHR(10) + ;
   &quot;   TYPE t_pk1Type2 IS TABLE OF NUMBER(5) &quot; + CHR(13) + CHR(10) + ;
   "   TYPE t_pk1Type2 IS TABLE OF NUMBER(5) " + CHR(13) + CHR(10) + ;
   &quot;   INDEX BY BINARY_INTEGER; &quot; + CHR(13) + CHR(10) + ;
   "   INDEX BY BINARY_INTEGER; " + CHR(13) + CHR(10) + ;
   &quot;   PROCEDURE proc1 &quot; + CHR(13) + CHR(10) + ;
   "   PROCEDURE proc1 " + CHR(13) + CHR(10) + ;
   &quot;   (  o_id          OUT  t_id, &quot; + CHR(13) + CHR(10) + ;
   "   (  o_id          OUT  t_id, " + CHR(13) + CHR(10) + ;
   &quot;       ao_course      OUT  t_Course, &quot; + CHR(13) + CHR(10) + ;
   "       ao_course      OUT  t_Course, " + CHR(13) + CHR(10) + ;
   &quot;       ao_dept        OUT  t_Dept &quot; + CHR(13) + CHR(10) + ;
   "       ao_dept        OUT  t_Dept " + CHR(13) + CHR(10) + ;
   &quot;   ); &quot; + CHR(13) + CHR(10) + ;
   "   ); " + CHR(13) + CHR(10) + ;
   &quot;   PROCEDURE proc2 &quot; + CHR(13) + CHR(10) + ;
   "   PROCEDURE proc2 " + CHR(13) + CHR(10) + ;
   &quot;   ( &quot; + CHR(13) + CHR(10) + ;
   "   ( " + CHR(13) + CHR(10) + ;
   &quot;         i_Arg1        IN  NUMBER, &quot; + CHR(13) + CHR(10) + ;
   "         i_Arg1        IN  NUMBER, " + CHR(13) + CHR(10) + ;
   &quot;         ao_Arg2        OUT  t_pk1Type1, &quot; + CHR(13) + CHR(10) + ;
   "         ao_Arg2        OUT  t_pk1Type1, " + CHR(13) + CHR(10) + ;
   &quot;         ao_Arg3        OUT  t_pk1Type2 &quot; + CHR(13) + CHR(10) + ;
   "         ao_Arg3        OUT  t_pk1Type2 " + CHR(13) + CHR(10) + ;
   &quot;   ); &quot; + CHR(13) + CHR(10) + ;
   "   ); " + CHR(13) + CHR(10) + ;
   &quot;   END FoxPackage; &quot;
   "   END FoxPackage; "
*!* Step 2 Create the package body string
*!* Step 2 Create the package body string
Proc_String2=&quot;CREATE OR REPLACE PACKAGE BODY FoxPackage AS &quot; + CHR(13) + ;
Proc_String2="CREATE OR REPLACE PACKAGE BODY FoxPackage AS " + CHR(13) + ;
   CHR(10) + &quot;   PROCEDURE  proc1 &quot; + CHR(13) + CHR(10) + ;
   CHR(10) + "   PROCEDURE  proc1 " + CHR(13) + CHR(10) + ;
   &quot;     ( &quot; + CHR(13) + CHR(10) + ;
   "     ( " + CHR(13) + CHR(10) + ;
   &quot;         o_id          OUT  t_id, &quot; + CHR(13) + CHR(10) + ;
   "         o_id          OUT  t_id, " + CHR(13) + CHR(10) + ;
   &quot;         ao_course      OUT  t_Course, &quot; + CHR(13) + CHR(10) + ;
   "         ao_course      OUT  t_Course, " + CHR(13) + CHR(10) + ;
   &quot;         ao_dept        OUT  t_Dept &quot; + CHR(13) + CHR(10) + ;
   "         ao_dept        OUT  t_Dept " + CHR(13) + CHR(10) + ;
   &quot;     ) &quot; + CHR(13) + CHR(10) + ;
   "     ) " + CHR(13) + CHR(10) + ;
   &quot;   AS &quot; + CHR(13) + CHR(10) + ;
   "   AS " + CHR(13) + CHR(10) + ;
   &quot;   BEGIN &quot; + CHR(13) + CHR(10) + ;
   "   BEGIN " + CHR(13) + CHR(10) + ;
   &quot;         o_id(1):= 200; &quot; + CHR(13) + CHR(10) + ;
   "         o_id(1):= 200; " + CHR(13) + CHR(10) + ;
   &quot;         ao_course(1) :=  'M101'; &quot; + CHR(13) + CHR(10) + ;
   "         ao_course(1) :=  'M101'; " + CHR(13) + CHR(10) + ;
   &quot;         ao_dept(1) :=  'EEE' ; &quot; + CHR(13) + CHR(10) + ;
   "         ao_dept(1) :=  'EEE' ; " + CHR(13) + CHR(10) + ;
   &quot;         o_id(2) := 201; &quot; + CHR(13) + CHR(10) + ;
   "         o_id(2) := 201; " + CHR(13) + CHR(10) + ;
   &quot;         ao_course(2) :=  'PHY320'; &quot; + CHR(13) + CHR(10) + ;
   "         ao_course(2) :=  'PHY320'; " + CHR(13) + CHR(10) + ;
   &quot;         ao_dept(2) :=  'ECE' ; &quot; + CHR(13) + CHR(10) + ;
   "         ao_dept(2) :=  'ECE' ; " + CHR(13) + CHR(10) + ;
   &quot;   END proc1; &quot; + CHR(13) + CHR(10) + ;
   "   END proc1; " + CHR(13) + CHR(10) + ;
   &quot;   PROCEDURE proc2 &quot; + CHR(13) + CHR(10) + ;
   "   PROCEDURE proc2 " + CHR(13) + CHR(10) + ;
   &quot;     ( &quot; + CHR(13) + CHR(10) + ;
   "     ( " + CHR(13) + CHR(10) + ;
   &quot;         i_Arg1        IN  NUMBER, &quot; + CHR(13) + CHR(10) + ;
   "         i_Arg1        IN  NUMBER, " + CHR(13) + CHR(10) + ;
   &quot;         ao_Arg2        OUT  t_pk1Type1, &quot; + CHR(13) + CHR(10) + ;
   "         ao_Arg2        OUT  t_pk1Type1, " + CHR(13) + CHR(10) + ;
   &quot;         ao_Arg3        OUT  t_pk1Type2 &quot; + CHR(13) + CHR(10) + ;
   "         ao_Arg3        OUT  t_pk1Type2 " + CHR(13) + CHR(10) + ;
   &quot;     ) &quot; + CHR(13) + CHR(10) + ;
   "     ) " + CHR(13) + CHR(10) + ;
   &quot;   AS &quot; + CHR(13) + CHR(10) + ;
   "   AS " + CHR(13) + CHR(10) + ;
   &quot;         i  NUMBER; &quot; + CHR(13) + CHR(10) + ;
   "         i  NUMBER; " + CHR(13) + CHR(10) + ;
   &quot;   BEGIN &quot; + CHR(13) + CHR(10) + ;
   "   BEGIN " + CHR(13) + CHR(10) + ;
   &quot;     FOR i IN 1 .. i_Arg1 LOOP &quot; + CHR(13) + CHR(10) + ;
   "     FOR i IN 1 .. i_Arg1 LOOP " + CHR(13) + CHR(10) + ;
   &quot;         ao_Arg2(i) := 'Row Number ' || to_char(i); &quot; + CHR(13) + ;
   "         ao_Arg2(i) := 'Row Number ' || to_char(i); " + CHR(13) + ;
             CHR(10) + ;
             CHR(10) + ;
   &quot;         END LOOP; &quot; + CHR(13) + CHR(10) + ;
   "         END LOOP; " + CHR(13) + CHR(10) + ;
   &quot;         FOR i IN 1 .. i_Arg1 LOOP &quot; + CHR(13) + CHR(10) + ;
   "         FOR i IN 1 .. i_Arg1 LOOP " + CHR(13) + CHR(10) + ;
   &quot;           ao_Arg3(i) := i; &quot; + CHR(13) + CHR(10) + ;
   "           ao_Arg3(i) := i; " + CHR(13) + CHR(10) + ;
   &quot;           END LOOP; &quot; + CHR(13) + CHR(10) + ;
   "           END LOOP; " + CHR(13) + CHR(10) + ;
   &quot;     END proc2; &quot; + CHR(13) + CHR(10) + ;
   "     END proc2; " + CHR(13) + CHR(10) + ;
   &quot;   END FoxPackage; &quot;
   "   END FoxPackage; "


*!* Note that the Server name, User ID, and Passwords in the following
*!* Note that the Server name, User ID, and Passwords in the following
Line 150: Line 150:
*!* Note that the Server name, User ID, and Passwords in the following
*!* Note that the Server name, User ID, and Passwords in the following
*!* string should be changed to reflect the environment.
*!* string should be changed to reflect the environment.
lcConnStr=&quot;DRIVER={Microsoft ODBC for Oracle};&quot; + ;
lcConnStr="DRIVER={Microsoft ODBC for Oracle};" + ;
     &quot;SERVER=MyServer;&quot; + ;
     "SERVER=MyServer;" + ;
     &quot;UID=MyUserID;PWD=MyPassword&quot;
     "UID=MyUserID;PWD=MyPassword"
*!* Create An ADO Connection
*!* Create An ADO Connection
oConnection=CREATEOBJECT(&quot;ADODB.Connection&quot;)
oConnection=CREATEOBJECT("ADODB.Connection")
oConnection.ConnectionString = lcConnStr
oConnection.ConnectionString = lcConnStr
oConnection.CursorLocation  = 3 &amp;&amp; Server Side Cursor
oConnection.CursorLocation  = 3 && Server Side Cursor
oConnection.OPEN
oConnection.OPEN
*!* Build strings that will be used to call the Oracle Package
*!* Build strings that will be used to call the Oracle Package
Proc_String1 = &quot;{call FoxPackage.Proc1({resultset 3, o_id , &quot; + ;
Proc_String1 = "{call FoxPackage.Proc1({resultset 3, o_id , " + ;
     &quot;ao_course, ao_dept})}&quot;
     "ao_course, ao_dept})}"
Proc_String2 = &quot;{call FoxPackage.Proc1({resultset 3, o_id}, &quot; + ;
Proc_String2 = "{call FoxPackage.Proc1({resultset 3, o_id}, " + ;
     &quot;{resultset 3, ao_course}, {resultset 3, ao_dept})}&quot;
     "{resultset 3, ao_course}, {resultset 3, ao_dept})}"
Proc_String3 = &quot;{call FoxPackage.Proc2(&quot; + ALLTRIM(STR(var1)) + ;
Proc_String3 = "{call FoxPackage.Proc2(" + ALLTRIM(STR(var1)) + ;
     &quot;,{resultset 3, ao_Arg2, ao_Arg3})}&quot;
     ",{resultset 3, ao_Arg2, ao_Arg3})}"
Proc_String4 = &quot;{call FoxPackage.Proc2(&quot; + ALLTRIM(STR(var2)) + ;
Proc_String4 = "{call FoxPackage.Proc2(" + ALLTRIM(STR(var2)) + ;
     &quot;,{resultset 3, ao_Arg2}, {resultset 3, ao_Arg3})}&quot;
     ",{resultset 3, ao_Arg2}, {resultset 3, ao_Arg3})}"


*!* Create An ADO recordset for the first resultset returned from Package Proc1
*!* Create An ADO recordset for the first resultset returned from Package Proc1
rs1=CREATEOBJECT(&quot;ADODB.Recordset&quot;)
rs1=CREATEOBJECT("ADODB.Recordset")
rs1.activeconnection        = oConnection
rs1.activeconnection        = oConnection
rs1.CursorLocation          = 3 &amp;&amp; Client Side Cursor
rs1.CursorLocation          = 3 && Client Side Cursor
rs1.cursortype              = 1 &amp;&amp; OpenKeyset
rs1.cursortype              = 1 && OpenKeyset
rs1.LockType                = 3 &amp;&amp; LockOptimistic
rs1.LockType                = 3 && LockOptimistic
rs1.OPEN(Proc_String1)
rs1.OPEN(Proc_String1)
rs1.movefirst
rs1.movefirst


*!* Create An ADO recordset for the second resultset returned from Package Proc1
*!* Create An ADO recordset for the second resultset returned from Package Proc1
rs2=CREATEOBJECT(&quot;ADODB.Recordset&quot;)
rs2=CREATEOBJECT("ADODB.Recordset")
rs2.activeconnection        = oConnection
rs2.activeconnection        = oConnection
rs2.CursorLocation          = 3 &amp;&amp; Client Side Cursor
rs2.CursorLocation          = 3 && Client Side Cursor
rs2.cursortype              = 1 &amp;&amp; OpenKeyset
rs2.cursortype              = 1 && OpenKeyset
rs2.LockType                = 3 &amp;&amp; LockOptimistic
rs2.LockType                = 3 && LockOptimistic
rs2.OPEN(Proc_String2)
rs2.OPEN(Proc_String2)
rs2.movefirst
rs2.movefirst


*!* Create An ADO recordset for the first resultset returned from Package Proc2
*!* Create An ADO recordset for the first resultset returned from Package Proc2
rs3=CREATEOBJECT(&quot;ADODB.Recordset&quot;)
rs3=CREATEOBJECT("ADODB.Recordset")
rs3.activeconnection        = oConnection
rs3.activeconnection        = oConnection
rs3.CursorLocation          = 3 &amp;&amp; Client Side Cursor
rs3.CursorLocation          = 3 && Client Side Cursor
rs3.cursortype              = 1 &amp;&amp; OpenKeyset
rs3.cursortype              = 1 && OpenKeyset
rs3.LockType                = 3 &amp;&amp; LockOptimistic
rs3.LockType                = 3 && LockOptimistic
rs3.OPEN(Proc_String3)
rs3.OPEN(Proc_String3)
rs3.movefirst
rs3.movefirst


*!* Create An ADO recordset for the second resultset returned from Package Proc2
*!* Create An ADO recordset for the second resultset returned from Package Proc2
rs4=CREATEOBJECT(&quot;ADODB.Recordset&quot;)
rs4=CREATEOBJECT("ADODB.Recordset")
rs4.activeconnection        = oConnection
rs4.activeconnection        = oConnection
rs4.CursorLocation          = 3 &amp;&amp; Client Side Cursor
rs4.CursorLocation          = 3 && Client Side Cursor
rs4.cursortype              = 1 &amp;&amp; OpenKeyset
rs4.cursortype              = 1 && OpenKeyset
rs4.LockType                = 3 &amp;&amp; LockOptimistic
rs4.LockType                = 3 && LockOptimistic
rs4.OPEN(Proc_String4)
rs4.OPEN(Proc_String4)
rs4.movefirst
rs4.movefirst


*!* Navigate through the first ADO Recordset
*!* Navigate through the first ADO Recordset
? &quot;Resultset 1&quot;
? "Resultset 1"
DO WHILE !rs1.EOF()
DO WHILE !rs1.EOF()
     FOR i=0 TO rs1.FIELDS.COUNT-1
     FOR i=0 TO rs1.FIELDS.COUNT-1
Line 214: Line 214:


*!* Navigate through the second ADO Recordset
*!* Navigate through the second ADO Recordset
? &quot;Resultset 2&quot;
? "Resultset 2"
DO WHILE !rs2.EOF()
DO WHILE !rs2.EOF()
     FOR i=0 TO rs2.FIELDS.COUNT-1
     FOR i=0 TO rs2.FIELDS.COUNT-1
Line 223: Line 223:


*!* Navigate through the third ADO Recordset
*!* Navigate through the third ADO Recordset
? &quot;Resultset 3&quot;
? "Resultset 3"
DO WHILE !rs3.EOF()
DO WHILE !rs3.EOF()
     FOR i=0 TO rs3.FIELDS.COUNT-1
     FOR i=0 TO rs3.FIELDS.COUNT-1
Line 232: Line 232:


*!* Navigate through the fourth ADO Recordset
*!* Navigate through the fourth ADO Recordset
? &quot;Resultset 4&quot;
? "Resultset 4"
DO WHILE !rs4.EOF()
DO WHILE !rs4.EOF()
     FOR i=0 TO rs4.FIELDS.COUNT-1
     FOR i=0 TO rs4.FIELDS.COUNT-1

Latest revision as of 13:47, 21 July 2020

Knowledge Base


How to return a resultset from Oracle stored procedures into an ADO recordset

Article ID: 239771

Article Last Modified on 2/24/2005



APPLIES TO

  • Microsoft Visual FoxPro 6.0 Professional Edition
  • Microsoft Visual FoxPro 7.0 Professional Edition
  • Microsoft Visual FoxPro 8.0 Professional Edition
  • Microsoft Visual FoxPro 9.0 Professional Edition



This article was previously published under Q239771

SUMMARY

This article illustrates how use the Microsoft ODBC Driver for Oracle version 2.0 and later with an Oracle PL/SQL package to return resultsets from an Oracle stored procedure to an ADO recordset.

MORE INFORMATION

With the release of the Microsoft ODBC Driver for Oracle version 2.0 and higher, it is possible to retrieve resultsets from Oracle stored procedures. By creating Oracle stored procedures that return parameters of type TABLE, row, and column, data can be returned that can then be manipulated and displayed as a resultset.

The resultsets created by the Microsoft ODBC Driver for Oracle version 2.0 and 2.5 using Oracle stored procedures are READ ONLY and Static. Retrieving a resultset requires the creation of an Oracle Package.

Before beginning to work with the Visual FoxPro application, an Oracle package called FoxPackage must be created. FoxPackage is taken from the Help File for Microsoft ODBC Driver for Oracle: Advanced Topics: "Returning Array Parameters from Stored Procedures".

Note The following code requires installation of Microsoft Data Access Components (MDAC) version 2.x or later. MDAC is included in the data components of Visual Studio 6.0 or can be downloaded from the following Web site:

  1. Create a program file named Procs.prg using the code snippet below. This code will be used to create an Oracle package definition and package body:

    *!* Step 1 Create the package definition string
    Proc_String1="CREATE OR REPLACE PACKAGE FoxPackage AS " + CHR(13) + ;
       CHR(10) + ;
       "   TYPE t_id is TABLE of  NUMBER(5) " + CHR(13) + CHR(10) + ;
       "    INDEX BY BINARY_INTEGER; " + CHR(13) + CHR(10) + ;
       "   TYPE t_Course is TABLE of VARCHAR2(10) " + CHR(13) + CHR(10) + ;
       "    INDEX BY BINARY_INTEGER; " + CHR(13) + CHR(10) + ;
       "   TYPE t_Dept is TABLE of VARCHAR2(5) " + CHR(13) + CHR(10) + ;
       "    INDEX BY BINARY_INTEGER; " + CHR(13) + CHR(10) + ;
       "   TYPE t_pk1Type1 IS TABLE OF VARCHAR2(100) " + CHR(13) + CHR(10) + ;
       "    INDEX BY BINARY_INTEGER; " + CHR(13) + CHR(10) + ;
       "   TYPE t_pk1Type2 IS TABLE OF NUMBER(5) " + CHR(13) + CHR(10) + ;
       "    INDEX BY BINARY_INTEGER; " + CHR(13) + CHR(10) + ;
       "   PROCEDURE proc1 " + CHR(13) + CHR(10) + ;
       "   (   o_id           OUT  t_id, " + CHR(13) + CHR(10) + ;
       "       ao_course      OUT  t_Course, " + CHR(13) + CHR(10) + ;
       "       ao_dept        OUT  t_Dept " + CHR(13) + CHR(10) + ;
       "   ); " + CHR(13) + CHR(10) + ;
       "   PROCEDURE proc2 " + CHR(13) + CHR(10) + ;
       "   ( " + CHR(13) + CHR(10) + ;
       "         i_Arg1         IN   NUMBER, " + CHR(13) + CHR(10) + ;
       "         ao_Arg2        OUT  t_pk1Type1, " + CHR(13) + CHR(10) + ;
       "         ao_Arg3        OUT  t_pk1Type2 " + CHR(13) + CHR(10) + ;
       "   ); " + CHR(13) + CHR(10) + ;
       "   END FoxPackage; "
    *!* Step 2 Create the package body string
    Proc_String2="CREATE OR REPLACE PACKAGE BODY FoxPackage AS " + CHR(13) + ;
       CHR(10) + "   PROCEDURE  proc1 " + CHR(13) + CHR(10) + ;
       "     ( " + CHR(13) + CHR(10) + ;
       "         o_id           OUT  t_id, " + CHR(13) + CHR(10) + ;
       "         ao_course      OUT  t_Course, " + CHR(13) + CHR(10) + ;
       "         ao_dept        OUT  t_Dept " + CHR(13) + CHR(10) + ;
       "     ) " + CHR(13) + CHR(10) + ;
       "   AS " + CHR(13) + CHR(10) + ;
       "   BEGIN " + CHR(13) + CHR(10) + ;
       "         o_id(1):= 200; " + CHR(13) + CHR(10) + ;
       "         ao_course(1) :=  'M101'; " + CHR(13) + CHR(10) + ;
       "         ao_dept(1) :=  'EEE' ; " + CHR(13) + CHR(10) + ;
       "         o_id(2) := 201; " + CHR(13) + CHR(10) + ;
       "         ao_course(2) :=  'PHY320'; " + CHR(13) + CHR(10) + ;
       "         ao_dept(2) :=  'ECE' ; " + CHR(13) + CHR(10) + ;
       "   END proc1; " + CHR(13) + CHR(10) + ;
       "   PROCEDURE proc2 " + CHR(13) + CHR(10) + ;
       "     ( " + CHR(13) + CHR(10) + ;
       "         i_Arg1         IN   NUMBER, " + CHR(13) + CHR(10) + ;
       "         ao_Arg2        OUT  t_pk1Type1, " + CHR(13) + CHR(10) + ;
       "         ao_Arg3        OUT  t_pk1Type2 " + CHR(13) + CHR(10) + ;
       "     ) " + CHR(13) + CHR(10) + ;
       "   AS " + CHR(13) + CHR(10) + ;
       "         i  NUMBER; " + CHR(13) + CHR(10) + ;
       "   BEGIN " + CHR(13) + CHR(10) + ;
       "      FOR i IN 1 .. i_Arg1 LOOP " + CHR(13) + CHR(10) + ;
       "         ao_Arg2(i) := 'Row Number ' || to_char(i); " + CHR(13) + ;
                 CHR(10) + ;
       "         END LOOP; " + CHR(13) + CHR(10) + ;
       "         FOR i IN 1 .. i_Arg1 LOOP " + CHR(13) + CHR(10) + ;
       "            ao_Arg3(i) := i; " + CHR(13) + CHR(10) + ;
       "            END LOOP; " + CHR(13) + CHR(10) + ;
       "      END proc2; " + CHR(13) + CHR(10) + ;
       "   END FoxPackage; "
    
    *!* Note that the Server name, User ID, and Passwords in the following
    *!* SQLSTRINGCONNECT should be changed to reflect the environment.
    gnConnHandle=SQLSTRINGCONN('DRIVER={Microsoft ODBC for Oracle};' + ;
       'SERVER=MyServer;UID=MyUserID;PWD=MyPassword')
    IF gnConnHandle>0
       Create_Pack=SQLEXEC(gnConnHandle,Proc_String1)
       IF Create_Pack>0
          Create_Body=SQLEXEC(gnConnHandle,Proc_String2)
       ENDIF
       =SQLDISCONN(gnConnHandle)
    ENDIF
                        
  2. Create a second program named Execado.prg using the code snippet below. This program will be used later to call the Oracle package:

    PARAMETER var1, var2
    PUBLIC oConnection,rs1,rs2,rs3,rs4,is_add
    LOCAL lcConnStr,lcAlias
    LOCAL Proc_String1,Proc_String2,Proc_String3,Proc_String4
    *!* Setup a DSN-Less connection to Sample Data Files
    *!* Note that the Server name, User ID, and Passwords in the following
    *!* string should be changed to reflect the environment.
    lcConnStr="DRIVER={Microsoft ODBC for Oracle};" + ;
        "SERVER=MyServer;" + ;
        "UID=MyUserID;PWD=MyPassword"
    *!* Create An ADO Connection
    oConnection=CREATEOBJECT("ADODB.Connection")
    oConnection.ConnectionString = lcConnStr
    oConnection.CursorLocation   = 3 && Server Side Cursor
    oConnection.OPEN
    *!* Build strings that will be used to call the Oracle Package
    Proc_String1 = "{call FoxPackage.Proc1({resultset 3, o_id , " + ;
        "ao_course, ao_dept})}"
    Proc_String2 = "{call FoxPackage.Proc1({resultset 3, o_id}, " + ;
        "{resultset 3, ao_course}, {resultset 3, ao_dept})}"
    Proc_String3 = "{call FoxPackage.Proc2(" + ALLTRIM(STR(var1)) + ;
        ",{resultset 3, ao_Arg2, ao_Arg3})}"
    Proc_String4 = "{call FoxPackage.Proc2(" + ALLTRIM(STR(var2)) + ;
        ",{resultset 3, ao_Arg2}, {resultset 3, ao_Arg3})}"
    
    *!* Create An ADO recordset for the first resultset returned from Package Proc1
    rs1=CREATEOBJECT("ADODB.Recordset")
    rs1.activeconnection         = oConnection
    rs1.CursorLocation           = 3 && Client Side Cursor
    rs1.cursortype               = 1 && OpenKeyset
    rs1.LockType                 = 3 && LockOptimistic
    rs1.OPEN(Proc_String1)
    rs1.movefirst
    
    *!* Create An ADO recordset for the second resultset returned from Package Proc1
    rs2=CREATEOBJECT("ADODB.Recordset")
    rs2.activeconnection         = oConnection
    rs2.CursorLocation           = 3 && Client Side Cursor
    rs2.cursortype               = 1 && OpenKeyset
    rs2.LockType                 = 3 && LockOptimistic
    rs2.OPEN(Proc_String2)
    rs2.movefirst
    
    *!* Create An ADO recordset for the first resultset returned from Package Proc2
    rs3=CREATEOBJECT("ADODB.Recordset")
    rs3.activeconnection         = oConnection
    rs3.CursorLocation           = 3 && Client Side Cursor
    rs3.cursortype               = 1 && OpenKeyset
    rs3.LockType                 = 3 && LockOptimistic
    rs3.OPEN(Proc_String3)
    rs3.movefirst
    
    *!* Create An ADO recordset for the second resultset returned from Package Proc2
    rs4=CREATEOBJECT("ADODB.Recordset")
    rs4.activeconnection         = oConnection
    rs4.CursorLocation           = 3 && Client Side Cursor
    rs4.cursortype               = 1 && OpenKeyset
    rs4.LockType                 = 3 && LockOptimistic
    rs4.OPEN(Proc_String4)
    rs4.movefirst
    
    *!* Navigate through the first ADO Recordset
    ? "Resultset 1"
    DO WHILE !rs1.EOF()
        FOR i=0 TO rs1.FIELDS.COUNT-1
            ? rs1.FIELDS(i).VALUE
        NEXT
        rs1.movenext
    ENDDO
    
    *!* Navigate through the second ADO Recordset
    ? "Resultset 2"
    DO WHILE !rs2.EOF()
        FOR i=0 TO rs2.FIELDS.COUNT-1
            ? rs2.FIELDS(i).VALUE
        NEXT
        rs2.movenext
    ENDDO
    
    *!* Navigate through the third ADO Recordset
    ? "Resultset 3"
    DO WHILE !rs3.EOF()
        FOR i=0 TO rs3.FIELDS.COUNT-1
            ? rs3.FIELDS(i).VALUE
        NEXT
        rs3.movenext
    ENDDO
    
    *!* Navigate through the fourth ADO Recordset
    ? "Resultset 4"
    DO WHILE !rs4.EOF()
        FOR i=0 TO rs4.FIELDS.COUNT-1
            ? rs4.FIELDS(i).VALUE
        NEXT
        rs4.movenext
    ENDDO
    
    *!* Done with the ADO Recordsets, so close
    rs1.CLOSE
    rs2.CLOSE
    rs3.CLOSE
    rs4.CLOSE
    *!* Done with the ADO Connection, so close
    oConnection.CLOSE
                        
  3. Run the Procs.prg program file to create the Oracle package.
  4. After the Procs procedure finishes executing, run the Execado program from the command line, using the following syntax:

    DO Execado WITH 3,3
                        
  5. Note that four different resultsets are returned to the Visual FoxPro desktop.


REFERENCES

For additional information about returning resultsets from Oracle stored procedures, click the following article number to view the article in the Microsoft Knowledge Base:

174679 How to retrieve resultsets from Oracle stored procedures


149882 How to execute a stored procedure on an Oracle server


Keywords: kbhowto kboracle kbdatabase KB239771