[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[转帖]一些ASP+OO4O(Oracle Object For OLE)的文章……

上一篇:[本站胡乱翻译]Oracle Objects for OLE (OO4O)简介……
下一篇:[备忘]Oracle在线帮助文档

添加日期:2007/7/19 4:39:55 快速返回   返回列表 阅读6406次
OO4O 簡介
( Oracle Object For Ole ) Oracle 所提供的 Native OLEDB Driver , 效能比 ADO 快 
--------------------------------------------------
方法 1: 使用 ORADC
設定使用元件 Oracle Data Control
設定 ORADC 的 Connect , DatabaseName 及 RecordSource 後

ORADC.Connect="UserID/Password"
ORADC.DataBaseName="DatabaseAliasName"
ORADC.RecordSource="TableName或SQL"
之後即可 oraDC.Recordset 來做資料的處理
-----------------------------------------------------
方法 2: 使用 OracleInProcServer 物件來做
透過 LateBinding 來 CreateObject

Set oraSession = CreateObject("OracleInProcServer.XoraSession") '--- 建立 Session 物件
Set oraDatabase = oraSession.OpenDatabase(DatabaseAlias,"UserID/Password", 1) '--- 建立 Database 物件
Set oraRecordset = oraDatabase.CreateDynaset(SQL, 4) '--- 建立 Recordset 物件

之後即可 oraRecordset 來做資料的處理 

VS.Net 可使用 ODP.Net ( Oracle Data Provider 4 .Net )

============================================================================

我在asp中使用oracle的OO4O,在oracle8和oracle8i中都正常,但在oracle9i却出错   
  请大虾指教   
    
  dim   cn   
  dim   oracn   
    
  set   cn=server.CreateObject("oracleinprocserver.xorasession")   
  set   oracn=cn.dbopendatabase("VMINFO","samples/samples",0)   
    
  最后一行出错,错误信息   
  unable   to   make   connectiong   ora-12638:身份证明搜索失败   
  我的环境   :win2000     oracle9I   
  oracle   object   for   OLE   已安装     
  wEB服务器和数据苦在同一台机器上   
  使用samples/samples@VMINFO可以登陆   
-----------------------
another   thing   to   try   is   to   turn   off   Oracle's   NT   authentication:   
    
Try   setting   the   following   in   the   sqlnet.ora   file   on   the   server: 

sqlnet.authentication_services=(none)   
-----------------------
谢谢,已经解决,顺便问一下   
  sqlnet的几个参数的作用
-----------------------
SQLNET.AUTHEN******   
  是用来设置认证的,参看  
================================================================

Oracle 8.1.7数据库服务器上OO4O不能执行的问题:
现象:
1。用OO4O连接数据库的VB程序,在客户机上可以正确执行,但在Oracle 8.1.7的数据库服务器(Win2K)上却无法执行
2。用OO4O连接数据库的ASP程序,在其它装了IIS的服务器上可以正确执行,但在Oracle 8.1.7的数据库服务器上却无法

执行
 
解决方法:
 
1。如果VB程序不能执行,重新安装OO4O即可,启动Oracle Universal Installer,然后选择Oracle Object for Ole
 
2。方法一:
 
ASP连接数据库,不能像VB程序那样,
用下面的CreateObject来创建OraSession对象
(也许有其他方法可以实现Session对象的直接创建,各位有兴趣可以研究一下):
 
   Set OraSession = Server.CreateObject("OracleInProcServer.XOraSession")
   Set OraDB = OraSession.OpenDatabase(dbAlias,UserName/Password,0)
 
而是应该在虚拟目录的Global.asa文件中写如下语句:


<OBJECT RUNAT=Server SCOPE=Application ID=OraSession 
        PROGID="OracleInProcServer.XOraSession"></OBJECT>


 
在Global.asa的Application_OnStart事件过程中增加下列语句(如果没有Application_OnStart事件过程,则需添加此

过程):
 

OraSession.CreateDatabasePool 1,40,200,dbAlias, UserName/Password, 0


 
然后在ASP程序中用下列方法打开数据库:
 

Set OraDB = OraSession.GetDatabaseFromPool(10)


 
注意:修改Global.asa后必须重新启动WWW服务。上述方法中各参数的意义请参考 Oracle Object for OLE Help 帮助文


 
方法二:

可以通过修改Oracle的用户认证方式,而不修改ASP程序的办法来解决。
但出于安全性的考虑,修改用户认证方式有时是不允许的。

修改方法如下:

将d:\oracle\ora81\network\admin\sqlnet.ora中的
sqlnet.authentication_services = (NTS)

改为
sqlnet.authentication_services = (none)
 
以后ASP程序即可正常执行。
=========================================================================
在ASP中通过oo4o连接Oracle数据库的例子

下面这段代码能够显示,当前用户所能够看到的所有的用户和表,有兴趣的, 可以把每个表的内容加上


<%
Dim objOraSession,objOraDb
Dim strDbUser,strDbPwd,strDbConn
Call ConnectDB()
Sub ConnectDB()
 '连接数据库 
 On Error Resume Next
 strDbUser  = "tmpUser"     '连接用户名
 strDbPwd  = "rt45ps1w"    '用户密码
 strDbConn = "sun450"       '连接字符串
 Set objOraSession  = Server.CreateObject("OracleInProcServer.XOraSession")
 Set objOraDB        = objOraSession.OpenDatabase(strDbConn,strDbUser & "/" & strDbPwd,0)
 If Err.Number>0 then
  Response.Write "<font color=red>错误 :" & err.description & "</font>"
  response.end
 End if
End Sub
Sub EndDB()
 Set objOraDB       = Nothing
 Set objOraSession = Nothing
End Sub
Function getTableList(str)
 Dim strSql,strTmp
 Dim objRs
  strSql = "Select at.table_name as tname,au.username as uname from all_tables at,all_users au Where 

au.username=at.owner order by au.username"
  Set objRs = objOraDb.DbCreateDynaset(strSql,0)
  While  Not objRs.Eof
   strA = objRs("uname") & "." & objRs("tname")
   If str=strA then
    strTmp = strTmp & "<option selected>" & strA & "</option>"
   Else
    strTmp = strTmp & "<option>" & strA & "</option>"
   End if
   objRs.MoveNext
  Wend 
 Set objRs = Nothing
 getTableList = strTmp
End Function
%>
<form name=form1 action="index.asp" method=POST target="main">
<table width="100%" border=0 align="center">
<tr><td>
All Tables : <select name="tb">
<%=getTableList(tblName)%>
</select>
<input type=hidden name="submitc" value="view">
<input type=submit name="submit" value="View Data">  <font color=red>(<%=strDbUser & "/" & strDbPwd & "@" 

& strDbConn%>)</font>
</td></tr>
</table>
</form>


============================================================
使用oo4o时Session没自动释放 
 
问题表现:
1. 程序使用 oo4o 连 Oracle 数据库,连接1段时间大约2-3小时后,客户端死掉,执行
ODatabase.ExecuteSQL方法返回 101 错误。此时,客户端使用TOAD连库,会报错
错误代码为 04031。

2. 当客户端程序执行其子线程时,不管怎么调用OSession和ODatabase的Close方法,
从TOAD中可以看到客户端机器连过来的Session一直都没有消掉。

3. 需要杀掉所有线程或者重新启动程序,才能继续用客户端读库和使用TOAD连库。

原因查找:
1. 焦点锁定在 Oracle服务器内的存储过程上,客户端调用库的存储过程时用到了游标。
2. 模拟实验1中,如果调用使用游标的存储过程,则Session关不掉。如果调用不使用游标的
存储过程,则Session可以关掉。模拟实验2中,如果在客户端调用游标时设置游标的属性
则,也能够实现Session的自动关闭。
该语句为 “ curParam.SetDynasetOption(ODYNASET_NOCACHE)? ”

{//。。。。。
OParameter curParam ;
ODynaset curDynaset;
curParam.SetDynasetOption(ODYNASET_NOCACHE);? //Important
curParam.GetValue(&curDynaset);
//。。。。。。
}

3. 继续查,发现问题在对数组边界的处理上。因为oo4o的OParameterCollection起始值比较特别。
当使用for循环调用 Param.Remove(i)时,其范围应该是 for (i = 1; i < nCount+1; i++),
而不是 for (i = 0; i < nCount; i++)。而之前使用的游标恰好在最后1位,因此没有被Remove。
所以误以为是因为游标或者其参数的问题。其实是数组边界问题。

参考:
1. http://skywheel.sarang.net/docs/Oracle/10g/win.101/b10119/o4c00051.htm
2. http://skywheel.sarang.net/docs/Oracle/10g/win.101/b10119/o4c00044.htm
3. http://skywheel.sarang.net/docs/Oracle/10g/win.101/b10119/o4c00052.htm
======================================================================
http://junglesong.yculblog.com/post.934359.html
从简化oo4o的数据库访问过程到工厂模式

Junglesong 发表于 2005-10-21 17:04:06 

大家应该还记得0040访问数据库的常用方式,是用SQL语句产生一个记录集OraDynaset,再对 
此记录集进行遍历操作,取出需要的数据。如果这样的代码混杂在程序的主要业务 
逻辑中,无疑会影响程序的可读性,代码也会有不必要的重复,所以我们可以将上 
述过程用一个函数包装一下,程序如下: 


‘// 函数注释:传入一个Sql语句,得到一个二维数组,数组元素类型为String。 
Public Function get2dArrayBySql(strSql As String) 
   '// 建立记录集 
   Dim OraDynaset As Object 
   Set OraDynaset = gOraDatabase.DbCreateDynaset(strSql, ORADYN_READONLY) 
    
   '// 建立并调整数组的大小 
   Dim arrayRetval() As String 
   ReDim arrayRetval(OraDynaset.recordcount, OraDynaset.fields.Count - 1) 
    
   '// 遍历记录集将数据传入数组 
   Dim i, j As Integer 
   While Not OraDynaset.EOF 
       For j = 0 To OraDynaset.fields.Count - 1 
           arrayRetval(i, j) = mfChgNull(OraDynaset.fields(j).Value) 
       Next 
       i = i + 1 
       OraDynaset.MoveNext 
   Wend 
    
   '// 将数组返回 
   get2dArrayBySql = arrayRetval 
End Function 



调用例子如下: 


   Dim arrayRowBody() As String 
   arrayRowBody = get2dArrayBySql(strSql) 



这样,程序的业务逻辑就和数据库的具体访问过程分开了,达到了高内聚,低耦合 
的目的。如果程序使用的数据库发生改变,只需变更get2dArrayBySql的访问过程 
就可以了,业务逻辑中的代码无需改变。 

上述函数还需要mfChgNull的辅助,当数据为空时可以传回一个零长度字符串。

 
Public Function mfChgNull(varData As Variant) As String 
On Error GoTo errorproc 

   If (IsNull(varData)) Then 
       mfChgNull = "" 
   Else 
       mfChgNull = CStr(varData) 
   End If 
    
   Exit Function 
errorproc: 
   mfChgNull = "" 
End Function 



在完全面向对象(c++,java,C#,vb.net)的语言中,代码还可以进一步发展,比如 
程序需要访问多种数据库,但业务逻辑都是一样的,这时可以制作一个数据库访 
问的基类,在其中实现数据库访问的各种接口函数(c++是纯虚函数,java是接口 
),然后在此基类上实现具体访问各种数据库的子类,具体由哪个类来访问具体的 
数据库由一个工厂类来判断,下面依次讲解: 

假设基类名为DbAccessBase, 
访问Oracle数据库的子类名为OracleDbAccessBase 
访问SqlServer数据库的子类名为SqlServerDbAccessBase 
访问MySql数据库的子类名为MySqlDbAccessBase 

他们都继承自DbAccessBase,类继承图如下 
DbAccessBase<-------OracleDbAccessBase 
                       | 
                       |___SqlServerDbAccessBase 
                       | 
                       |___MySqlDbAccessBase 


DbAccessBase有一个接口函数get2dArrayBySql,三个子类都分别实现了这个接口函数. 



下面用伪代码来说明具体实现 


DbAccessBase  dbAccess; 

if(数据库类型==Oracle数据库){ 
        dbAccess=new OracleDbAccessBase(); 

else if(数据库类型==SqlServer数据库){ 
        dbAccess=new SqlServerDbAccessBase(); 

else{ 
        dbAccess=new MySqlDbAccessBase(); 



以后直接使用dbAccess这个实例来访问数据库即可,业务逻辑无需关注数据库的详 
细情况. 

工厂类就是用来将刚才的代码包装一下,它的具体结构如下: 


class DbAccessFactory{ 
        public static gettDbAccessInstance(String 数据库类型){ 
                 DbAccessBase  dbAccess; 
                          if(数据库类型==Oracle数据库){ 
                                   dbAccess=new OracleDbAccessBase(); 
                          } 
                          else if(数据库类型==SqlServer数据库){ 
                                   dbAccess=new SqlServerDbAccessBase(); 
                          } 
                          else{ 
                                   dbAccess=new MySqlDbAccessBase(); 
                          } 

                          return dbAccess; 
        } 



然后我们的调用过程就简化成如下代码: 


DbAccessBase  dbAccess=DbAccessFactory.gettDbAccessInstance(数据库类型) 



如果需要增添一种数据库访问,实现DbAccessBase的一个子类,并在DbAccessFactory中多加一 
个判断就可以了,其它都不需要修改. 

大道至简,Hibernate对多数据库的访问实现不过如此. 
====================================================================
 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved