动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > 数据库 > Oracle教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
数据库:数据库教程,数据库技巧,Oracle教程,MySQL教程,Sybase教程,Access教程,DB2教程,数据库安全,数据库文摘
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ Oracle教程 ]的信息

本月文章推荐
.关于谁需要Web服务事务处理的具体.
.优化Oracle数据 获取角斗士般的性.
.Oracle常见错误代码的分析与解决.
.Oracle 10g中SCN与TimeStamp的斗.
.在codesmith中去掉oracle下划线.
.Oracle DBA 审计数据库试题选.
.ORA-600 [2103]错误解决过程.
.甲骨文Sun联手 构建新10年战略伙.
.各个平台上调整最大SGA区的方法.
.Linux ADSL Multipath Routing S.
.Oracle数据库PL/SQL过程调试的输.
.Oracle 恢复管理器 (RMAN) 的功能.
.如何在你的Linux机器上安装运行O.
.ORACLE 面试问题-技术篇.
.oracle数据库备份与恢复 a piece.
.PCTFREE与PCTUSED对高性能和有效.
.Oracle数据库备份技巧.
.在Oracle中重新编译所有无效的存.
.oracle_sid,server_name,网络连接.
.ORACLE要点综述(之一:基本SELEC.

ResultSetsfromStoredProceduresInOracle

发表日期:2008-2-9 |


Result Sets from Stored Procedures In Oracle

A frequently asked question is: I'd like to know whether ORACLE supports procedures (functions) which
returns result sets. The answer is most definitely yes.  In short, it'll look like this:
 
create or replace function sp_ListEmp return types.cursortype
as
    l_cursor    types.cursorType;
begin
    open l_cursor for select ename, empno from emp order by ename;
    return l_cursor;
end;
/
With 7.2 on up of the database you have cursor variables.  Cursor variables are cursors opened by a pl/sql routine and fetched from by another application or pl/sql routine (in 7.3 pl/sql routines can fetch from cursor variables as well as open them). The cursor variables are opened with the privelegs of the owner of the procedure and behave just like they were completely contained within the pl/sql routine. It uses the inputs to decide what database it will run a query on. Here is an example:
 
create or replace package types
as
    type cursorType is ref cursor;
end;
/
create or replace function sp_ListEmp return types.cursortype
as
    l_cursor    types.cursorType;
begin
    open l_cursor for select ename, empno from emp order by ename;
    return l_cursor;
end;
/
examples for SQLPlus, Pro*C, Java/JDBC, ODBC, ADO/ASP, DBI Perl and OCI follow:
REM SQL*Plus commands to use a cursor variable
variable c refcursor
exec :c := sp_ListEmp
print c

and the Pro*C to use this would look like:
static void process()
{
EXEC SQL BEGIN DECLARE SECTION;
    SQL_CURSOR  my_cursor;
    VARCHAR     ename[40];
    int         empno;
EXEC SQL END DECLARE SECTION;
    EXEC SQL WHENEVER SQLERROR DO sqlerror_hard();
    EXEC SQL ALLOCATE :my_cursor;
    EXEC SQL EXECUTE BEGIN
        :my_cursor := sp_listEmp;
    END; END-EXEC;
    for( ;; )
    {
        EXEC SQL WHENEVER NOTFOUND DO break;
        EXEC SQL FETCH :my_cursor INTO :ename, empno;
        printf( "'%.*s', %d\n", ename.len, ename.arr, empno );
    }
    EXEC SQL CLOSE :my_cursor;
}

And the java to use this could be:
 
import java.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
 
class curvar
{
  public static void main (String args [])
                     throws SQLException, ClassNotFoundException
  {
      String driver_class = "oracle.jdbc.driver.OracleDriver";
      String connect_string = "jdbc:oracle:thin:@slackdog:1521:oracle8";
      String query = "begin :1 := sp_listEmp; end;";
      Connection conn;
      Class.forName(driver_class);
      conn = DriverManager.getConnection(connect_string, "scott", "tiger");
      CallableStatement cstmt = conn.prepareCall(query);
      cstmt.registerOutParameter(1,OracleTypes.CURSOR);
      cstmt.execute();
      ResultSet rset = (ResultSet)cstmt.getObject(1);
      while (rset.next ())
        System.out.println( rset.getString (1) );
      cstmt.close();
  }
}

  The following is thanks to marktoml@hotmail.com (mark tomlinson)..
  If you use ODBC here is a working example, but it requires the use of the
8.0.5.2.0 or later Oracle ODBC driver, and an 8.0.5 server.
'
' 1) Create a form with 1 Text control (Text1) and 1 List Control (List1) and
'    1 Button (BTnExecute).
' 2) The only code that you need is a Click method on your button. Here is the Code.
'
'
Private Sub btnExecute_Click()
'PL/SQL Code
'===========
'
'CREATE OR REPLACE package reftest as
' cursor c1 is select ename from emp;
' type empCur is ref cursor return c1%ROWTYPE;
' Procedure GetEmpData(en in varchar2,EmpCursor in out empCur);
'END;
'
'
'CREATE OR REPLACE package body reftest as
'   Procedure GetEmpData
'(en in varchar2,EmpCursor in out empCur) is
'begin
' open EmpCursor for select ename from emp where ename LIKE en;
'end;
'end;
'
     Dim cn As New rdoConnection
     Dim qd As rdoQuery
     Dim rs As rdoResultset
     Dim cl As rdoColumn
     Static Number As Integer
     List1.Clear
     Number = 0
     cn.Connect = "uid=scott; pwd=tiger; DSN=MSLANGORL;"
     'enable the MS Cursor library
     cn.CursorDriver = rdUseOdbc
     'Make the connection
     cn.EstablishConnection rdNoDriverPrompt
     sSQL = "{call RefTest.GetEmpData(?,?)}"
     Set qd = cn.CreateQuery("", sSQL)
     qd.rdoParameters(0).Type = rdTypeVARCHAR
     qd(0).Direction = rdParamInputOutput
     qd(0).Value = Text1.Text
     qd.rdoParameters(1).Type = rdTypeVARCHAR
     'Dynamic or Keyset is meaningless here
     Set rs = qd.OpenResultset(rdOpenStatic)
     Do
        Debug.Print
        Debug.Print
        Do Until rs.EOF
            For Each cl In rs.rdoColumns
                 If IsNull(cl.Value) Then
                    List1.AddItem "(null)"
                    ' Debug.Print " "; cl.Name; "NULL"; Error trap for
null fields
                Else
                    List1.AddItem cl.Value
                    ' Debug.Print " "; cl.Name; " "; cl.Value;
                End If
            Next
            Debug.Print
            rs.MoveNext
        Loop
     Loop While rs.MoreResults
     cn.Close
End Sub


  And now, for a full ASP example (thanks to Jim Hoien and John Durst ) <%@ Language=VBScript %> <!--#INCLUDE VIRTUAL="/ADOVBS.INC" --> <% ' This demonstration draws heavily from the information contained in the article at ' http://govt.us.oracle.com/~tkyte/ResultSets/index.Html ' with special attention to the details provided by Mark Tomlinson. ' Make sure you have the correct Oracle ODBC driver so it will support Ref Cursors. ' ' ' This demonstration was a joint project by Jim Hoien (jhoien@yahoo.com) and John Durst (jpdurst@yahoo.com) ' ' These are the statements used on the Oracle server: ' ' /*******************************************************************************************/ ' /* Create the EMP demo table and populate. (extracted from Oracle's provided demobld.sql) */ ' /*******************************************************************************************/ ' ' CREATE TABLE EMP ' (EMPNO NUMBER(4) NOT NULL, ' ENAME VARCHAR2(10), ' JOB VARCHAR2(9), ' MGR NUMBER(4), ' HIREDATE DATE, ' SAL NUMBER(7,2), ' COMM NUMBER(7,2), ' DEPTNO NUMBER(2)); ' ' INSERT INTO EMP VALUES ' (7369,'SMITH','CLERK',7902,'17-DEC-80',800,NULL,20); ' INSERT INTO EMP VALUES ' (7499,'ALLEN','SALESMAN',7698,'20-FEB-81',1600,300,30); ' INSERT INTO EMP VALUES ' (7521,'WARD','SALESMAN',7698,'22-FEB-81',1250,500,30); ' INSERT INTO EMP VALUES ' (7566,'JONES','MANAGER',7839,'2-APR-81',2975,NULL,20); ' INSERT INTO EMP VALUES ' (7654,'MARTIN','SALESMAN',7698,'28-SEP-81',1250,1400,30); ' INSERT INTO EMP VALUES ' (7698,'BLAKE','MANAGER',7839,'1-MAY-81',2850,NULL,30); ' INSERT INTO EMP VALUES ' (7782,'CLARK','MANAGER',7839,'9-JUN-81',2450,NULL,10); ' INSERT INTO EMP VALUES ' (7788,'SCOTT','ANALYST',7566,'09-DEC-82',3000,NULL,20); ' INSERT INTO EMP VALUES ' (7839,'KING','PRESIDENT',NULL,'17-NOV-81',5000,NULL,10); ' INSERT INTO EMP VALUES ' (7844,'TURNER','SALESMAN',7698,'8-SEP-81',1500,0,30); ' INSERT INTO EMP VALUES ' (7876,'ADAMS','CLERK',7788,'12-JAN-83',1100,NULL,20); ' INSERT INTO EMP VALUES ' (7900,'JAMES','CLERK',7698,'3-DEC-81',950,NULL,30); ' INSERT INTO EMP VALUES ' (7902,'FORD','ANALYST',7566,'3-DEC-81',3000,NULL,20); ' INSERT INTO EMP VALUES ' (7934,'MILLER','CLERK',7782,'23-JAN-82',1300,NULL,10); ' ' /*******************************************************************************************/ ' /* Create a packaged procedure that accepts a department number and returns the employees. */ ' /* [Note: A standalone procedure will not work, it must be a packaged procedure!] */ ' /*******************************************************************************************/ ' ' CREATE OR REPLACE ' PACKAGE DEPARTMENT AS ' TYPE CURSOR_TYPE IS REF CURSOR; ' PROCEDURE GET_EMPS (I_DEPTNO IN NUMBER, ' O_RESULT_SET OUT CURSOR_TYPE); ' END; ' / ' CREATE OR REPLACE ' PACKAGE BODY DEPARTMENT AS ' PROCEDURE GET_EMPS (I_DEPTNO IN NUMBER, ' O_RESULT_SET OUT CURSOR_TYPE) ' AS ' BEGIN ' OPEN O_RESULT_SET FOR ' SELECT EMPNO, ENAME ' FROM EMP ' WHERE DEPTNO = I_DEPTNO; ' END; ' END; ' / %> <HTML> <HEAD> <TITLE>Oracle ADO Test</TITLE> </HEAD> <BODY> <H2>Test of ADO and Oracle Stored Procedures using Ref Cursors</H2> <% Dim objConn Dim connString Dim cmdStoredProc Dim param1 Dim testDeptNo testDeptNo = 10 ' testDeptNo = 20 ' testDeptNo = 30 set objConn = server.createobject("adodb.connection") ' System DSN connection ' Replace the values below with your own connString = "DSN=<YourDSN>;UID=<YourUserName>;PWD=<YourPassWord>" objConn.Open connString Set cmdStoredProc = Server.CreateObject ("ADODB.Command") Set cmdStoredProc.ActiveConnection = objConn cmdStoredProc.CommandText = "Department.Get_Emps" cmdStoredProc.CommandType = adCmdStoredProc Set param1 = cmdStoredProc.CreateParameter ("Dept_ID", adInteger, adParamInput) cmdStoredProc.Parameters.Append param1 param1.Value = testDeptNo Set rs = cmdStoredProc.Execute Response.Write ("<h3>Employees in Department # " & testDeptNo & "</h3>" & vbCrLf) Response.Write ("<p>" & vbCrLf) Response.Write ("<table>" & vbCrLf) Response.Write (" <tr>" & vbCrLf) Response.Write (" <th>Emp #</th>" & vbCrLf) Response.Write (" <th>Name</th>" & vbCrLf) Response.Write (" </tr>" & vbCrLf) While (Not rs.EOF) Response.Write (" <tr>" & vbCrLf) Response.Write (" <td>" & rs (0) & "</td>" & vbCrLf) Response.Write (" <td>" & rs (1) & "</td>" & vbCrLf) Response.Write (" </tr>" & vbCrLf) rs.MoveNext Wend Response.Write ("</table>" & vbCrLf) rs.Close objConn.Close Set rs = nothing Set param1 = nothing Set cmdStoredProc = nothing Set objConn = nothing %> </BODY> </HTML>
And the following is thanks to Brett Rosen : I noticed that you didn't have an OCI entry on http://osi.oracle.com/~tkyte/ResultSets/index.html . Here is OCI code to do this (Oracle 81) if you want to include it on that page. Some error checking and cleanup has been removed, but the below should work. (once dbname has been replaced appropriately) Brett int main(int argc, char* argv[]) { OCIError* pOciError; char* pConnectChar = "dbname"; char* pUsernameChar = "scott"; char* pPasswordChar = "tiger"; int answer; OCIStmt* pOciStatement; char* sqlCharArray = "BEGIN :sUCcess := sp_ListEmp; END;"; int id; char ename[40]; OCIEnv* g_pOciEnvironment = NULL; OCIServer* g_pOciServer = NULL; OCISession* g_pOciSession = NULL; OCISvcCtx* g_pOciServiceContext = NULL; sb2* pIndicator=0; sb2* pIndicator2=0; sb2* pIndicator3=0; OCIDefine* pOciDefine; OCIDefine* pOciDefine2; OCIBind* pBind; OCIStmt* cursor; answer = OCIInitialize(OCI_THREADED, NULL, NULL, NULL, NULL); answer = OCIEnvInit(&g_pOciEnvironment, OCI_DEFAULT, 0, NULL); answer = OCIHandleAlloc(g_pOciEnvironment, (void **)&pOciError, OCI_HTYPE_ERROR, 0, NULL); answer = OCIHandleAlloc(g_pOciEnvironment, (void **)&g_pOciSession, OCI_HTYPE_SESSION, 0, NULL); answer = OCIHandleAlloc(g_pOciEnvironment, (void **)&g_pOciServer, OCI_HTYPE_SERVER, 0, NULL); answer = OCIHandleAlloc(g_pOciEnvironment, (void **)&g_pOciServiceContext, OCI_HTYPE_SVCCTX, 0, NULL); answer = OCIServerAttach(g_pOciServer, pOciError, (unsigned char *)pConnectChar, strlen(pConnectChar), OCI_DEFAULT); answer = OCIAttrSet(g_pOciSession, OCI_HTYPE_SESSION, (unsigned char *)pUsernameChar, strlen(pUsernameChar), OCI_ATTR_USERNAME, pOciError); answer = OCIAttrSet(g_pOciSession, OCI_HTYPE_SESSION, (unsigned char *)pPasswordChar, strlen(pPasswordChar), OCI_ATTR_PASSWORD, pOciError); answer = OCIAttrSet(g_pOciServiceContext, OCI_HTYPE_SVCCTX, g_pOciServer, 0, OCI_ATTR_SERVER, pOciError); answer = OCIAttrSet(g_pOciServiceContext, OCI_HTYPE_SVCCTX, g_pOciSession, 0, OCI_ATTR_SESSION, pOciError); answer = OCISessionBegin(g_pOciServiceContext, pOciError, g_pOciSession, OCI_CRED_RDBMS, OCI_DEFAULT); answer = OCIHandleAlloc(g_pOciEnvironment, (void **)(&pOciStatement), OCI_HTYPE_STMT, 0, NULL); answer = OCIStmtPrepare(pOciStatement, pOciError, (unsigned char *)sqlCharArray, strlen(sqlCharArray), OCI_NTV_SYNTAX, OCI_DEFAULT); answer = OCIHandleAlloc(g_pOciEnvironment, (void **)(&cursor), OCI_HTYPE_STMT, 0, NULL); answer = OCIBindByPos(pOciStatement,&pBind, pOciError, 1, &cursor, 0,SQLT_RSET, pIndicator2, 0,NULL, 0,0,OCI_DEFAULT); answer = OCIStmtExecute(g_pOciServiceContext, pOciStatement, pOciError, 1, 0, NULL, NULL, OCI_COMMIT_ON_SUCCESS); answer = OCIDefineByPos(cursor,&pOciDefine, pOciError,2,&id,sizeof(int), SQLT_INT,pIndicator, 0, 0,OCI_DEFAULT); answer = OCIDefineByPos(cursor,&pOciDefine2, pOciError,1,ename,40, SQLT_STR,pIndicator3, 0, 0,OCI_DEFAULT); if (answer == 0) while ((answer = OCIStmtFetch(cursor,pOciError, 1,OCI_FETCH_NEXT,OCI_DEFAULT)) == 0) { printf("fetched id %d and name %s\n",id,ename); } answer = OCIHandleFree(pOciError, OCI_HTYPE_ERROR); return 0; }
And the following DBI perl example is thanks to q_richard_chen@yahoo.com (Richard Chen):Hello Tom, I was looking for such compilation of tips on the topic. I did not find the section about doing it using the popular perl DBI. After some fiddling I get it working there too. Here is a complete working example following your model using perl DBI. I think it is a good idea that you include this in your howto so that more people will benefit from it. Thanks Richard Chen $ cat demo.pl #!/usr/local/bin/perl -w use strict; use DBI; use DBD::Oracle qw(:ora_types); my $dbh = DBI->connect('dbi:Oracle:','scott','tiger') or die $DBI::errstr; my $sth1 = $dbh->prepare(q{create or replace package types as type cursorType is ref cursor; end;}); $sth1->execute; > > $sth1 = $dbh->prepare(q{ create or replace function sp_ListEmp return types.cursorType as l_cursor types.cursorType; begin open l_cursor for select ename, empno from emp order by ename; return l_cursor; end;}); $sth1->execute; $sth1 = $dbh->prepare(q{ BEGIN :cursor := sp_ListEmp; END; }); my $sth2; $sth1->bind_param_inout(":cursor", \$sth2, 0, { ora_type => ORA_RSET } ); $sth1->execute(); while ( my @row = $sth2->fetchrow_array ) { print join("",@row),"\n"; }
MFC + ODBC VERSION (example checked by Marcin Buchwald) marcin.buchwald@gazeta.pl Oracle server side code is just like in the VB example CDatabase m_DB; BOOL ok = m_DB.OpenEx(_T("DSN=orcl;UID=velvet"),CDatabase::useCursorLib); COraSet set(&m_DB); set.m_Value = Text1.Text; set.Open(); while (!set.IsEOF()) { // set members contain values of single row // use it here set.MoveNext(); } set.Close(); where COraSet::COraSet(CDatabase* pdb) : CRecordset(pdb) { m_nParams = 1; m_nFields = ; m_nDefaultType = snapshot; } CString COraSet::GetDefaultSQL() { return _T("{call RefTest.GetEmpData(?,?)}"); }
上一篇:oracle自动imp脚本 人气:1392
下一篇:[基础]9i新特性之五闪回查询 人气:516
浏览全部Oracle教程的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-10-10 企业网站智能管理系统(TZIMS) v6
2008-10-10 拓文asp.net网站内容管理系统 v6
2008-10-10 动网论坛PHP版 v2.0++ Build 081
2008-10-10 免费时代CMS v5.0
2008-10-10 wodig第四季中文DIGG社区 v4.1 b
2008-10-10 老Y文章管理系统 v2.2 bulid 081
2008-10-10 魔法盒动感相册 ASP+SQL版 v2.0
2008-10-10 Asoft签到管理系统 v3.0 Pack1
2008-10-10 哥特人音乐网潮流留言本 v1.1
2008-10-11 联系人分组工具 v1.1 中文破解版
2008-10-11 FaceMelter变脸 v2.0 汉化破解版
2008-10-11 PathTracker道路跟踪仪 v1.2 破解
2008-10-11 Rooms手机聊天室 v0.6.7 破解版
2008-10-11 RemoteDesktop远程桌面 v1.0 破解
2008-10-11 ProRemote远程调音台 v1.0.1 破解
2008-10-11 PicShare照片共享 v1.0.0 破解版
2008-10-11 Photogene照片编辑器 v1.5 汉化破
2008-10-11 WriteRoom共享文档 v1.0 破解版
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | js/vbs加密 | md5加密 | 进制转换 | UTF-8 转换工具 | Html转换js | Html转换asp | Html转换php | Html转换perl
实用工具:汉字翻译拼音 | 拼音字典 | 符号对照表 | 个税计算 | 实时汇率查询换算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 | 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報
防水工事·改修工事 フットサル大会 探偵
SEO対策 中国語教室 ホームページ作成