破宝

我是一块破破烂烂的宝贝石头。
随笔 - 94, 评论 - 1281, 引用 - 52

导航

关于

自选精华版 RECOMMENDATIONS
留言板 GUESTBOOK

本人 blog 文章、图片及其他资源等,除另有声明外,均遵循以下原则向全球(当然包括朝鲜、古巴、利比亚等国)共享:

1。欢迎转载、复制、传播、引用,但转载、复制(包括但不仅限于作为参考资料复制到本地)、传播、引用同时必须在显著位置注明作者(破宝/percyboy)和文章原始 URL 地址等信息。但商业转载、复制、传播(尤指用于图书、光盘等媒体的部分或全部),须事先征得本人的许可。

2。文章以“现状”提供,不为由于使用本站资源而造成的任何损失而负责,仅提供力所能及的咨询和参考意见。

3。关于修改:允许您将本 blog 中的资源作为参考资料复制时的一定修改,但仍须保留作者和出处信息;其他情况下的修改(包括修改后再发布),须和本人确认许可。
 

标签

每月存档

最新留言

广告

 

长期以来,我一直用的是 MS SQL Server / Access 数据库,通过 .NET 访问 MS 自家的东西几乎没碰到过什么麻烦。最近项目中要用 Oracle 作为数据库,学习研究了一些 .NET 访问 Oracle 的东西,发现问题倒真的不少。

1。System.Data.OracleClient 和 System.Data.OleDb 命名空间

虽然通过这两个命名空间的类都可以访问 Oracle 数据库,但和 SQL Server 类似的(System.Data.SqlClient 命名空间的类效率要比 System.Data.OleDb 命名空间中的类高一些),System.Data.OracleClient 命名空间中的类要比 System.Data.OleDb 命名空间的类效率高一些(这一点我没有亲自验证,但大多数地方都会这么说,而且既然专门为 Oracle 作的东西理论上也应该专门作过针对性的优化)。

当然还有另一点就是从针对性上说,System.Data.OracleClient 要更好一些:

比如数据类型,System.Data.OleDb.OleDbType 枚举中所列的就没有 System.Data.OracleClient.OracleType 枚举中的那些有针对性;另外,Oracle 的 Number 类型如果数字巨大,超出 .NET 数据类型范围的情况中,就必须使用 System.Data.OracleClient 中的专门类 -- OracleNumber 类型。

好了,不再赘述这两个的比较,下面主要讨论 System.Data.OracleClient 命名空间中的类型,即 ADO.NET for Oracle Data Provider (数据提供程序)。

2。数据库连接:

无论是 System.Data.OleDb 还是 System.Data.OracleClient 访问 Oracle 都需要在 .NET 运行的机器(ASP.NET 中就是 Web 服务器)安装 Oracle 客户端组件。(这一点是和 MS 的两种数据库不同的,MS 的东西安装 MDAC: Microsoft Data Access Component 2.6 以上版本后,就无须再安装 SQL Server 客户端或者 Office 软件,就能访问。)

System Requirements:

(1)如用 System.Data.OracleClient 访问 Oracle,客户端组件版本应在 Oracle 8i Client Release 3 (8.1.7)以上版本。MS 只确保访问 Oracle 8.1.6、Oracle 8.1.7、Oracle 9i 服务器时的情况。MDAC 2.6 以上。

(2)如用 System.Data.OleDb 访问 Oracle,客户端组件版本 7.3.3.4.0 以上或 8.1.7.4.1 以上。MDAC 2.6 以上。

如服务器为 Oracle8i 以上,客户端组件版本应为 8.0.4.1.1c。

在 .NET 运行的机器中,安装 Oracle 客户端,然后打开 Net Manager (Oracle 9i) / Easy Config (Oracle 8i) 按你以前的经验设置本地服务的映射(这里的服务名将用于数据库连接串)。

System.Data.OracleClient 中访问 Oracle 数据库的连接串是:

User ID=用户名; Password=密码; Data Source=服务名

(上述为一般的连接串,详细的连接串项目可以在 System.Data.OracleClient.OracleConnection.ConnectionString 属性的文档中找到。)

System.Data.OleDb 中的访问 Oracle 数据库的连接串是:

Provider=MSDAORA.1; User ID=用户名; Password=密码; Data Source=服务名

3。Oracle 中的数据类型:

Oracle 的数据类型和 SQL Server 相比,要“奇怪”一些:SQL Server 的大多数据类型很容易找到 .NET 中比较接近的类型,Oracle 中的类型就离 .NET 类型远了许多,毕竟 Oracle 是和 Java 亲近的数据库。

  • number: 数字类型,一般是 Number(M,N),M是有效数字,N是小数点后的位数(默认0),这个是按十进制说的。
  • nvarchar2: 可变长字符型(Unicode),这个比较像 SQL Server 的 nvarchar(但不知 Oracle 为什么加了个“2”)。(去掉“n”为非 Unicode 的,下同。)
  • nchar: 定长字符型(Unicode)。
  • nclob: “写作文”的字段,存储大量字符(Unicode)时用。
  • date: 日期类型,比较接近 SQL Server 的 datetime。

Oracle 中字段不能是 bit 或者 bool 之类的类型,一般是 number(1) 代替的。

和 SQL Server 一样在 SQL 命令中,字符类型需要用单引号(')隔开,两个单引号('')是单引号的字符转义(比如: I'm fat. 写入一个 SQL 命令是: UPDATE ... SET ...='I''m fat.' ...)。

比较特殊的是日期类型:比如要写入 2004-7-20 15:20:07 这个时刻需要如下写:

UPDATE ... SET ... = TIMESTAMP '2004-7-20 15:20:07' ...

注意这里使用了 TIMESTAMP 关键字,并使用单引号隔开;另外请注意日期格式,上面的格式是可识别的,Oracle 识别的格式没有 SQL Server 那般多。这是和 SQL Server 不同的地方。

顺便提一句:Access 中的日期类型是用井号(#)隔开的,UPDATE ... SET ... = #2004-7-20 15:20:07# ...

4。访问 Oracle 过程/函数(1)

SQL Server 作程序时经常使用存储过程,Oracle 里也可以使用过程,还可以使用函数。Oracle 的过程似乎是不能有返回值的,有返回值的就是函数了(这点有些像 BASIC,函数/过程区分的很细致。SQL Server 存储过程是可以有返回值的)。

.NET 访问 Oracle 过程/函数的方法很类似于 SQL Server,例如:

OracleParameter[] parameters = {
    new OracleParameter("ReturnValue", OracleType.Int32, 0, ParameterDirection.ReturnValue, true, 0, 0, "",
         DataRowVersion.Default, Convert.DBNull )
    new OracleParameter("参数1", OracleType.NVarChar, 10),
    new OracleParameter("参数2",  OracleType.DateTime),
    new OracleParameter("参数3",  OracleType.Number, 1)
 };

parameters[1].Value = "test";
parameters[2].Value = DateTime.Now;
parameters[3].Value = 1;                        // 也可以是 new OracleNumber(1);

OracleConnection connection = new OracleConnection( ConnectionString );
OracleCommand command = new OracleCommand("函数/程名", connection);
command.CommandType = CommandType.StoredProcedure;

foreach(OracleParameter parameter in parameters)
     command.Parameters.Add( parameter );

connection.Open();
command.ExecuteNonQuery();
int returnValue = parameters[0].Value; //接收函数返回值
connection.Close();

Parameter 的 DbType 设定请参见 System.Data.OracleClient.OracleType 枚举的文档,比如:Oracle 数据库中 Number 类型的参数的值可以用 .NET decimal 或 System.Data.OracleClient.OracleNumber 类型指定; Integer 类型的参数的值可以用 .NET int 或 OracleNumber 类型指定。等等。

上面例子中已经看到函数返回值是用名为“ReturnValue”的参数指定的,该参数为 ParameterDirection.ReturnValue 的参数。

5。访问 Oracle 过程/函数 (2)

不返回记录集(没有 SELECT 输出)的过程/函数,调用起来和 SQL Server 较为类似。但如果想通过过程/函数返回记录集,在 Oracle 中就比较麻烦一些了。

在 SQL Server 中,如下的存储过程:

CREATE PROCEDURE GetCategoryBooks
(
    @CategoryID int
)
AS
SELECT * FROM Books
WHERE CategoryID = @CategoryID
GO

在 Oracle 中,请按以下步骤操作:

(1)创建一个包,含有一个游标类型:(一个数据库中只需作一次)

CREATE OR REPLACE PACKAGE Test
  AS
       TYPE Test_CURSOR IS REF CURSOR;
END Test;

(2)过程:

CREATE OR REPLACE PROCEDURE GetCategoryBooks
(
     p_CURSOR out Test.Test_CURSOR,    -- 这里是上面包中的类型,输出参数
     p_CatogoryID INTEGER
)
AS
BEGIN
     OPEN p_CURSOR FOR
           SELECT * FROM Books
           WHERE CategoryID=p_CatogoryID;
END GetCategoryBooks;

(3).NET 程序中:

OracleParameters parameters = {
     new OracleParameter("p_CURSOR", OracleType.CURSOR, 2000, ParameterDirection.Output, true, 0, 0, "",
          DataRowVersion.Default, Convert.DBNull),
     new OracleParameter("p_CatogoryID", OracleType.Int32)
};

parameters[1].Value = 22;

OracleConnection connection = new OracleConnection( ConnectionString );
OracleCommand command = new OracleCommand("GetCategoryBooks", connection);
command.CommandType = CommandType.StoredProcedure;

foreach(OracleParameter parameter in parameters)
     command.Parameters.Add( parameter );

connection.Open();
OracleDataReader dr = command.ExecuteReader();

while(dr.Read())
{
    // 你的具体操作。这个就不需要我教吧?
}
connection.Close();

另外有一点需要指出的是,如果使用 DataReader 取得了一个记录集,那么在 DataReader 关闭之前,程序无法访问输出参数和返回值的数据。

 

好了,先这些,总之 .NET 访问 Oracle 还是有很多地方和 SQL Server 不同的,慢慢学习了。

(转载请注明 作者:破宝(percyboy) 出处:博客堂

打印 | 张贴于 2004-08-06 15:35:00 | Tag:暂无标签

留言反馈

#NET 访问 Oracle 数据库相关 编辑
.NET访问Oracle数据库相关 长期以来,我一直用的是MSSQLServer/Access数据库,通过.NET访问MS自家的东西几乎没碰到过什么麻烦。最近项目中要用...
2007-03-04 01:00:00 | [匿名:ipusr]
#re: .NET 访问 Oracle 数据库相关 编辑
无意中找到你的博客,看看 ,觉得不错,
在一细看,竟然是自己的师兄啊,校友,郑州大学的,
好亲啊,感觉,…………刚毕业,感觉什么都不会,呵呵
以后多多指教啊,QQ:52093511
2006-09-12 09:58:00 | [匿名:liulihong]
#re: .NET 访问 Oracle 数据库相关 编辑
我服务器用的是oracle817,用vb2005做了个应用程序通过system.data.oracle.clent访问数据库,本地访问正常,但通过click once发布后,报数据库连接超时,用sqlplus连接正常,不知为什么,请指教!谢谢.
2006-03-03 11:56:00 | [匿名:zhan_hx@hotmail.com]
#Qustion on use of named parameters 编辑
How to use named parameter with oledb? My VB code:

sql="select * from table1 where fld1=:fld1value;"

cmd.parameters.add(new OleDbParameter("fld1value", "xxxxx"))

does not work. So how to use oledb with named parameters? Thanks!
2005-12-22 13:30:00 | [匿名:Gege]
#re: .NET 访问 Oracle 数据库相关 编辑
RE:安装了visual studio.net。使用vb.net.net framework显示1.1版本。在输入
import system.data.oracleclinent时,提示没有这个命名空间。请各位高手帮我解决这个问题。

在项目中添加对system.data.oracleclinent.dll的引用。
2005-08-21 21:53:00 | [匿名:scoutzjf@163.com]
#re: .NET 访问 Oracle 数据库相关 编辑
安装了visual studio.net。使用vb.net.net framework显示1.1版本。在输入
import system.data.oracleclinent时,提示没有这个命名空间。请各位高手帮我解决这个问题。
2005-08-12 17:49:00 | [匿名:maysunny]
#re: .NET 访问 Oracle 数据库相关 编辑
有帮我回答的么,我等着呢啊
2005-08-09 08:46:00 | [匿名:sun]
#re: .NET 访问 Oracle 数据库相关 编辑
请问:有下面提示错误,怎么解决呢,谢谢
无法加载oci.dll(System.DllNotFoundException),可oci.dll明明就在c:\oracle\ora92\bin目录下,path中也有这个目录设置。
2005-08-09 08:44:00 | [匿名:sun]
#关于Microsoft.ApplicationBlocks.Data.dll的使用 编辑
各位大哥,老师让我用Microsoft.ApplicationBlocks.Data.dll做dll连接oracle,但是这个dll只支持sql,我该怎么修改这个dll里的内容阿
2005-07-27 10:07:00 | [匿名:我是小猪猪]
#re: .NET 访问 Oracle 数据库相关 编辑
如果我要查询oracle中在两个时间段内的数据时,SQL命令应该怎么写啊?
比如:

DateTime nows=DateTime.Now;
this.TextBox1.Text=nows.ToString();
this.TextBox2.Text=nows.ToString();

string hwsel="select ch,pmsm,dwsm,hwh,jz,xcsj,jcr from llgscljsb where hwh='"+this.DropDownList1.SelectedValue+"' and xcsj>='"+this.TextBox1.Text+"' and xcsj<='"+this.TextBox2.Text+"'";
在SQL中我试了是可以的,可在oracle中就是不行,提示:文字与格式字符串不匹配
2005-05-30 13:52:00 | [匿名:zswc]
#.NET 访问 Oracle 数据库相关 编辑
Ping Back来自:blog.csdn.net
2005-04-24 23:51:00 | [匿名:夏天]
#re: .NET 访问 Oracle 数据库相关 编辑
关于nchar和nvarchar2,我个人认为nvarchar2中2的含义为最大的字符数量可以是nchar字符数量的2倍。是4000与2000的关系。
2005-04-08 12:42:00 | [匿名:yi34567]
#re: .NET 访问 Oracle 数据库相关 编辑
to 路人家:
请添加对程序集“System.Data.Oracleclient.dll”的引用。
2005-03-27 20:03:00 | [匿名:破宝]
#re: .NET 访问 Oracle 数据库相关 编辑
Framework1.1为何不能引用System.Data.OracleClient ??
2005-03-27 00:04:00 | [匿名:路人家]
#re: .NET 访问 Oracle 数据库相关 编辑
可是 System.Data.OracleClient 在那里下载?
2005-02-25 17:59:00 | [匿名:gare1000]
#re: .NET 访问 Oracle 数据库相关 编辑
Error while trying to retrieve text for error ORA-01019
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Data.OleDb.OleDbException: Error while trying to retrieve text for error ORA-01019

Source Error:


Line 8: OleDbConnection conn = new OleDbConnection("Provider=MSDAORA.1;User=sdycdevuser;Password=sdycdevuser;Data Source=orahz");
Line 9: OleDbCommand cmd = new OleDbCommand(SQL,conn);
Line 10: conn.Open();
Line 11: OleDbDataReader read;
Line 12: read=cmd.ExecuteReader();

2004-10-29 11:17:00 | [匿名:zhrl]
#re: .NET 访问 Oracle 数据库相关 编辑
Could not create an environment: OCIEnvCreate returned -1.
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

异常详细信息: System.Exception: Could not create an environment: OCIEnvCreate returned -1.


请指教
2004-10-26 09:22:00 | [匿名:zhrl]
#.NET 访问 Oracle 数据库相关 编辑
Ping Back来自:blog.csdn.net
2004-10-19 10:41:00 | [匿名:allun]
#re: .NET 访问 Oracle 数据库相关 编辑
在asp访问sql server 存储过程的时候如果有输出参数和结果集,那么在结果集关闭之前,也是无法获得输出参数和输出参数的。
2004-09-21 08:29:00 | [匿名:塞北的雪]
#re: .NET 访问 Oracle 数据库相关 编辑
谢谢你从前对我的帮助!
等待了你好久了,终于看到你了,我好高兴!
2004-08-11 23:35:00 | [匿名:swc]
#re: .NET 访问 Oracle 数据库相关 编辑
纠正一下:如服务器为 Oracle8i 以上,客户端组件版本应为 8.0.4.1.1c。oracleclient的版本号是随着.net framework的升级而变化的,不是依赖于server端的oracle版本。

另外,对于sql/oracle调用存储过程的时候,前缀的使用,我想有必要讲一下。

总结的很系统,学习ing。。。
2004-08-07 12:40:00 | [匿名:juqiang]
#re: .NET 访问 Oracle 数据库相关 编辑
写入日期我也是使用to_date,今天又知道了另一种方法。

返回结果集真的有些麻烦,不适应,还是觉得mssql做的更舒服些。

但使用了一段时间的oracle后,oracle也有设计的不错的地方,写起存储过程来,也挺好玩的。
2004-08-07 11:46:00 | [匿名:gcs]
#re: .NET 访问 Oracle 数据库相关 编辑
惭愧自己做了这么久却从未如此系统的总结过。

关于如何写入日期类型,我一直用如下方式,有些麻烦。
UPDATE ... SET ... = TO_DATE('1980-08-24 22:22:22', 'YYYY-MM-DD HH24:MI:SS')
2004-08-06 19:43:00 | [匿名:宽带鱼]
#re: .NET 访问 Oracle 数据库相关 编辑
太好了,正用得上,谢谢
2004-08-06 17:17:00 | [匿名:aspsir]
对不起,目前本随笔不允许发表新评论.

Powered by: Joycode.MVC引擎 0.5.2.0