위 링크처럼 EXEC가 아닌 CALL로 호출하는데 {}로 감싸줘야한다.
이거때문에 개고생했네
Enabling Result Sets (Programming)
more..
Oracle reference cursors (Result Sets) allow an application to retrieve data using stored procedures and stored functions. The following information identifies how to use reference cursors to enable Result Sets through ODBC.Procedure call:{CALL Example1(?)}{CALL RSET.Example1(?)}Function Call:{? = CALL Example1(?)}{? = CALL RSET.Example1(?)}
- The ODBC syntax for calling stored procedures must be used. Native PL/SQL is not supported through ODBC. The following identifies how to call the procedure or function without a package and within a package. The package name in this case is RSET.
{CALL RSET.Example2("Literal 1", "Literal 2")}
- The PL/SQL reference cursor parameters may be omitted when calling the procedure, however, if one reference cursor parameter is specified, all must be specified. For example, assume procedure Example2 is defined to have four parameters. Parameters 1 and 3 are reference cursor parameters and parameters 2 and 4 are character strings. The call can be specified in the following two ways:
In the following example, parameters 1 and 3 contain reference cursor parameters.
{CALL RSET.Example2(?,"Literal 1", ?,"Literal 2")}Note: In versions of the Oracle8 ODBC Driver previous to release 8.1.5.3.0, each reference cursor parameter for a procedure or function had to contain parameter marker(s) on the call statement. The reference cursor parameter(s) did not need to be bounded by the calling application. If the calling application did bind the parameter, the Oracle8 ODBC Driver ignored it and bound the reference cursor parameter(s) internally.The following example application shows how to return a Result Set using the Oracle8 ODBC Driver:/** Sample Application using Oracle reference cursors via ODBC** Assumptions:** 1) Oracle Sample database is present with data loaded for the EMP table.** 2) Two fields are referenced from the EMP table ename and mgr.** 3) A data source has been setup to access the sample database.*** Program Description:** Abstract:** This program demonstrates how to return result sets using* Oracle stored procedures** Details:** This program:* Creates an ODBC connection to the database.* Creates a Packaged Procedure containing two result sets.* Executes the procedure and retrieves the data from both result sets.* Displays the data to the user.* Deletes the package then logs the user out of the database.*** The following is the actual PL/SQL this code generates to* create the stored procedures.*DROP PACKAGE ODBCRefCur;CREATE PACKAGE ODBCRefCur ASTYPE ename_cur IS REF CURSOR;TYPE mgr_cur IS REF CURSOR;PROCEDURE EmpCurs(Ename IN OUT ename_cur, Mgr IN OUT mgr_cur, pjob IN VARCHAR2);END;/CREATE PACKAGE BODY ODBCRefCur ASPROCEDURE EmpCurs(Ename IN OUT ename_cur, Mgr IN OUT mgr_cur, pjob IN VARCHAR2)ASBEGINIF NOT Ename%ISOPENTHENOPEN Ename for SELECT ename from emp;END IF;IF NOT Mgr%ISOPENTHENOPEN Mgr for SELECT mgr from emp where job = pjob;END IF;END;END;/** End PL/SQL for Reference Cursor.*//** Include Files*/#include <windows.h>#include <stdio.h>#include <sql.h>#include <sqlext.h>/** Defines*/#define JOB_LEN 9#define DATA_LEN 100#define SQL_STMT_LEN 500/** Procedures*//** Main Program*/int main(){SQLHENV hEnv;SQLHDBC hDbc;SQLHSTMT hStmt;SQLRETURN rc;char *DefUserName ="scott";char *DefPassWord ="tiger";SQLCHAR ServerName[DATA_LEN];SQLCHAR *pServerName=ServerName;SQLCHAR UserName[DATA_LEN];SQLCHAR *pUserName=UserName;SQLCHAR PassWord[DATA_LEN];SQLCHAR *pPassWord=PassWord;char Data[DATA_LEN];SQLINTEGER DataLen;char error[DATA_LEN];char *charptr;SQLCHAR SqlStmt[SQL_STMT_LEN];SQLCHAR *pSqlStmt=SqlStmt;char *pSalesMan = "SALESMAN";SQLINTEGER sqlnts=SQL_NTS;/** Allocate the Environment Handle*/rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv );if (rc != SQL_SUCCESS){printf( "Cannot Allocate Environment Handle\n");printf( "\nHit Return to Exit\n");charptr = gets ((char *)error);exit(1);}/** Set the ODBC Version*/rc = SQLSetEnvAttr( hEnv,SQL_ATTR_ODBC_VERSION,(void *)SQL_OV_ODBC3,0);if (rc != SQL_SUCCESS){printf( "Cannot Set ODBC Version\n");printf( "\nHit Return to Exit\n");charptr = gets ((char *)error);exit(1);}/** Allocate the Connection handle*/rc = SQLAllocHandle( SQL_HANDLE_DBC, hEnv, &hDbc );if (rc != SQL_SUCCESS){printf( "Cannot Allocate Connection Handle\n");printf( "\nHit Return to Exit\n");charptr = gets ((char *)error);exit(1);}/** Get User Information*/lstrcpy( (char *) pUserName, DefUserName );lstrcpy( (char *) pPassWord, DefPassWord );/** Data Source name*/printf( "\nEnter the ODBC Data Source Name\n" );charptr = gets ((char *) ServerName);/** User Name*/printf ( "\nEnter User Name Default [%s]\n", pUserName);charptr = gets ((char *) UserName);if (*charptr == '\0'){lstrcpy( (char *) pUserName, (char *) DefUserName );}/** Password*/printf ( "\nEnter Password Default [%s]\n", pPassWord);charptr = gets ((char *)PassWord);if (*charptr == '\0'){lstrcpy( (char *) pPassWord, (char *) DefPassWord );}/** Connection to the database*/rc = SQLConnect( hDbc,pServerName,(SQLSMALLINT) lstrlen((char *)pServerName),pUserName,(SQLSMALLINT) lstrlen((char *)pUserName),pPassWord,(SQLSMALLINT) lstrlen((char *)pPassWord));if (rc != SQL_SUCCESS){DisplayError(SQL_HANDLE_DBC, hDbc, "SQLConnect");}/** Allocate a Statement*/rc = SQLAllocHandle( SQL_HANDLE_STMT, hDbc, &hStmt );if (rc != SQL_SUCCESS){printf( "Cannot Allocate Statement Handle\n");printf( "\nHit Return to Exit\n");charptr = gets ((char *)error);exit(1);}/** Drop the Package*/lstrcpy( (char *) pSqlStmt, "DROP PACKAGE ODBCRefCur");rc = SQLExecDirect(hStmt, pSqlStmt, lstrlen((char *)pSqlStmt));/** Create the Package Header*/lstrcpy( (char *) pSqlStmt, "CREATE PACKAGE ODBCRefCur AS\n");lstrcat( (char *) pSqlStmt, " TYPE ename_cur IS REF CURSOR;\n");lstrcat( (char *) pSqlStmt, " TYPE mgr_cur IS REF CURSOR;\n\n");lstrcat( (char *) pSqlStmt, " PROCEDURE EmpCurs (Ename IN OUT ename_cur,");lstrcat( (char *) pSqlStmt, "Mgr IN OUT mgr_cur,pjob IN VARCHAR2);\n\n");lstrcat( (char *) pSqlStmt, "END;\n");rc = SQLExecDirect(hStmt, pSqlStmt, lstrlen((char *)pSqlStmt));if (rc != SQL_SUCCESS){DisplayError(SQL_HANDLE_STMT, hStmt, "SQLExecDirect");}/** Create the Package Body*/lstrcpy( (char *) pSqlStmt, "CREATE PACKAGE BODY ODBCRefCur AS\n");lstrcat( (char *) pSqlStmt, " PROCEDURE EmpCurs (Ename IN OUT ename_cur,");lstrcat( (char *) pSqlStmt, "Mgr IN OUT mgr_cur, pjob IN VARCHAR2)\n AS\n BEGIN\n");lstrcat( (char *) pSqlStmt, " IF NOT Ename%ISOPEN\n THEN\n");lstrcat( (char *) pSqlStmt, " OPEN Ename for SELECT ename from emp;\n");lstrcat( (char *) pSqlStmt, " END IF;\n\n");lstrcat( (char *) pSqlStmt, " IF NOT Mgr%ISOPEN\n THEN\n");lstrcat( (char *) pSqlStmt, " OPEN Mgr for SELECT mgr from emp where job = pjob;\n");lstrcat( (char *) pSqlStmt, " END IF;\n");lstrcat( (char *) pSqlStmt, " END;\n");lstrcat( (char *) pSqlStmt, "END;\n");rc = SQLExecDirect(hStmt, pSqlStmt, lstrlen((char *)pSqlStmt));if (rc != SQL_SUCCESS){DisplayError(SQL_HANDLE_STMT, hStmt, "SQLExecDirect");}/** Bind the Parameter*/rc = SQLBindParameter(hStmt,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,JOB_LEN,0,pSalesMan,0,&sqlnts);/** Call the Store Procedure which executes the Result Sets*/lstrcpy( (char *) pSqlStmt, "{CALL ODBCRefCur.EmpCurs(?)}");rc = SQLExecDirect(hStmt, pSqlStmt, lstrlen((char *)pSqlStmt));if (rc != SQL_SUCCESS){DisplayError(SQL_HANDLE_STMT, hStmt, "SQLExecDirect");}/** Bind the Data*/rc = SQLBindCol( hStmt,1,SQL_C_CHAR,Data,sizeof(Data),&DataLen);if (rc != SQL_SUCCESS){DisplayError(SQL_HANDLE_STMT, hStmt, "SQLBindCol");}/** Get the data for Result Set 1*/printf( "\nEmployee Names\n\n");while ( rc == SQL_SUCCESS ){rc = SQLFetch( hStmt );if ( rc == SQL_SUCCESS ){printf("%s\n", Data);}else{if (rc != SQL_NO_DATA){DisplayError(SQL_HANDLE_STMT, hStmt, "SQLFetch");}}}printf( "\nFirst Result Set - Hit Return to Continue\n");charptr = gets ((char *)error);/** Get the Next Result Set*/rc = SQLMoreResults( hStmt );if (rc != SQL_SUCCESS){DisplayError(SQL_HANDLE_STMT, hStmt, "SQLMoreResults");}/** Get the data for Result Set 2*/printf( "\nManagers\n\n");while ( rc == SQL_SUCCESS ){rc = SQLFetch( hStmt );if ( rc == SQL_SUCCESS ){printf("%s\n", Data);}else{if (rc != SQL_NO_DATA){DisplayError(SQL_HANDLE_STMT, hStmt, "SQLFetch");}}}printf( "\nSecond Result Set - Hit Return to Continue\n");charptr = gets ((char *)error);/** Should Be No More Results Sets*/rc = SQLMoreResults( hStmt );if (rc != SQL_NO_DATA){DisplayError(SQL_HANDLE_STMT, hStmt, "SQLMoreResults");}/** Drop the Package*/lstrcpy( (char *) pSqlStmt, "DROP PACKAGE ODBCRefCur");rc = SQLExecDirect(hStmt, pSqlStmt, lstrlen((char *)pSqlStmt));/** Free handles close connections to the database*/SQLFreeHandle( SQL_HANDLE_STMT, hStmt );SQLDisconnect( hDbc );SQLFreeHandle( SQL_HANDLE_DBC, hDbc );SQLFreeHandle( SQL_HANDLE_ENV, hEnv );printf( "\nAll Done - Hit Return to Exit\n");charptr = gets ((char *)error);return(0);}/** Display Error Messages*/
- oid DisplayError( SWORD HandleType, SQLHANDLE hHandle, char *Module );
{SQLCHAR MessageText[255];SQLCHAR SQLState[80];SQLRETURN rc=SQL_SUCCESS;LONG NativeError;SWORD RetLen;SQLCHAR error[25];char *charptr;rc = SQLGetDiagRec(HandleType,hHandle,1,SQLState,&NativeError,MessageText,255,&RetLen);printf( "Failure Calling %s\n", Module );if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO){printf( "\t\t\t State: %s\n", SQLState);printf( "\t\t\t Native Error: %d\n", NativeError );printf( "\t\t\t Error Message: %s\n", MessageText );}printf( "\nHit Return to Exit\n");charptr = gets ((char *)error);exit(1);}
- oid DisplayError( SWORD HandleType, SQLHANDLE hHandle, char *Module )
Posted by shiftkey


