oracle表的历史数据转储过程,C#连接Oracle数据库通过存储过程操作数据库 - cuizm的专栏 - CSDN博客...
C#连接Oracle数据库通过存储过程操作数据库 收藏 此文于2011-06-07被推荐到CSDN首页
此文于2011-06-08被推荐到CSDN首页
如何被推荐?
之前笔者一直用C#连接SQL Server数据库。近期由于工作需要,需要用C#连接Oracle数据库,并且要通过存储过程,来操作数据库中的数据,实现增、删、改、查(有分页功能)功能。并且,为了今后对数据库扩展方便,对现在的代码改动最小的情况下,实现数据库的平稳切换,必须采用OleDB的方式连接Oracle数据库、操作存储过程。
首先去网上搜索资料,确实找到了很多C#连接Oracle数据库,和用存储过程操作数据库的资料。但是仔细研究发现,清一色的全部是使用OracleClient(Oracle专用驱动)的方式对Oracle数据库及存储过程进行操作。没办法,只能自己动手、丰衣足食。经过3天左右的辛苦努力,终于实现了用OleDB连接Oracle数据库,并且用存储过程来操作Oracle数据库的方法。下面将实现方式总结一下。
用OleDB操作Oracle存储过程,有几个难题;
1、 返回记录集,也就是Oracle的游标;
2、 对于某些特殊的应用,有可能需要返回多个记录集;
3、 将存储过程中的数据,通过输出参数的形式返回给程序(因为要做分页,需要将记录数输出来);
4、 对Text大文本字段(对应Oracle的数据类型是CLOB)的增、改、查操作;
5、 对特殊字符的查询,如查询文本中是否包含“%”、“\”、“’”、“_”等符号;
接下来,主要针对以上问题,进行介绍;
一、连接Oracle数据库
连接Oracle数据库,主要有2种方式。一种是使用微软的数据库驱动进行连接;另外一种是使用Oracle的数据库驱动进行连接;
经过在网上查资料,说是Oracle的数据库驱动,中文可能会出现乱码;微软的驱动虽然中文没有乱码,但是对于CLOB类型的字段,无法操作;经过对比,决定使用Oracle的数据库驱动。因为应用中,肯定要有CLOB类型的字段操作;但是经过测试,未发现中文出现乱码的情况;
Ø Oracle数据库连接方式:
Provider=OraOLEDB.Oracle.1;User ID=username;password=dbpassword;Data Source=databasename;Persist Security Info=True;Extended Properties='PLSQLRSet=1';
Extended Properties='PLSQLRSet=1'
注意:上面这个属性一定要带上,否则无法操作有返回游标参数的存储过程;
Ø 微软的数据库连接方式:
Provider=MSDAORA.1;Data Source=allrun;User ID=allrunadmin;Password=allrun;Persist Security Info=True;
建议使用Oracle数据库的连接方式。
二、存储过程,返回多个记录集
Oracle存储过程脚本:
view plaincopy to clipboardprint?
--包
create or replace
PACKAGE "DESKTOP_PAGE_PACKAGE" as
TYPE T_CURSOR IS REF CURSOR;
procedure GetDesktopPage (RecordTotal OUT NUMBER, curRecordTotal OUT T_CURSOR, curDesktopPage OUT T_CURSOR);
end;
--包体
create or replace
PACKAGE BODY "DESKTOP_PAGE_PACKAGE" as
procedure GetDesktopPage (RecordTotal OUT NUMBER, curRecordTotal OUT T_CURSOR, curDesktopPage OUT T_CURSOR) is
begin
--记录集1
OPEN curRecordTotal FOR
SELECT 1679 FROM DUAL;
--记录集2
OPEN curDesktopPage FOR
SELECT * FROM DESKTOP_PAGE;
--输出参数
RecordTotal := 1688;
end;
end;
--包
create or replace
PACKAGE "DESKTOP_PAGE_PACKAGE" as
TYPE T_CURSOR IS REF CURSOR;
procedure GetDesktopPage (RecordTotal OUT NUMBER, curRecordTotal OUT T_CURSOR, curDesktopPage OUT T_CURSOR);
end;
--包体
create or replace
PACKAGE BODY "DESKTOP_PAGE_PACKAGE" as
procedure GetDesktopPage (RecordTotal OUT NUMBER, curRecordTotal OUT T_CURSOR, curDesktopPage OUT T_CURSOR) is
begin
--记录集1
OPEN curRecordTotal FOR
SELECT 1679 FROM DUAL;
--记录集2
OPEN curDesktopPage FOR
SELECT * FROM DESKTOP_PAGE;
--输出参数
RecordTotal := 1688;
end;
end;
C#程序操作存储过程:
view plaincopy to clipboardprint?
OleDbCommand store = new OleDbCommand ();
store.Parameters.Clear ();
store.Connection = con;
store.CommandType = CommandType.StoredProcedure;
store.CommandText = "DESKTOP_PAGE_PACKAGE.GetDesktopPage";
store.Parameters.Add ("RecordTotal", OleDbType.Numeric).Value = null;
store.Parameters["RecordTotal"].Size = -1;
store.Parameters["RecordTotal"].Scale = 0;
store.Parameters["RecordTotal"].Precision = 0;
store.Parameters["RecordTotal"].Direction = ParameterDirection.Output;
try
{
OleDbDataAdapter da = new OleDbDataAdapter (store);
DataSet ds = new DataSet ();
da.Fill (ds);
Response.Write ("输出参数返回记录数:" + store.Parameters["RecordTotal"].Value + "
");
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
Response.Write ("记录集1返回记录数:" + ds.Tables[0].Rows[i][0] + "
");
}
Response.Write ("
记录集2返回数据:
");
for (int i = 0; i < ds.Tables[1].Rows.Count; i++)
{
Response.Write (ds.Tables[1].Rows[i][0] + ", " + ds.Tables[1].Rows[i][1] + ", " + ds.Tables[1].Rows[i][2] + "
");
}
}
finally
{
con.Close ();
}
OleDbCommand store = new OleDbCommand ();
store.Parameters.Clear ();
store.Connection = con;
store.CommandType = CommandType.StoredProcedure;
store.CommandText = "DESKTOP_PAGE_PACKAGE.GetDesktopPage";
store.Parameters.Add ("RecordTotal", OleDbType.Numeric).Value = null;
store.Parameters["RecordTotal"].Size = -1;
store.Parameters["RecordTotal"].Scale = 0;
store.Parameters["RecordTotal"].Precision = 0;
store.Parameters["RecordTotal"].Direction = ParameterDirection.Output;
try
{
OleDbDataAdapter da = new OleDbDataAdapter (store);
DataSet ds = new DataSet ();
da.Fill (ds);
Response.Write ("输出参数返回记录数:" + store.Parameters["RecordTotal"].Value + "
");
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
Response.Write ("记录集1返回记录数:" + ds.Tables[0].Rows[i][0] + "
");
}
Response.Write ("
记录集2返回数据:
");
for (int i = 0; i < ds.Tables[1].Rows.Count; i++)
{
Response.Write (ds.Tables[1].Rows[i][0] + ", " + ds.Tables[1].Rows[i][1] + ", " + ds.Tables[1].Rows[i][2] + "
");
}
}
finally
{
con.Close ();
}
因为主要是介绍操作数据库存储过程的方法,如何连接数据库请自己写;
一、对CLOB字段的增、改、查;
假设表名为:DESKTOP_PAGE,包含2个字段:USERCODE(普通字符串)、CONTENT(CLOB类型)
Oracle存储过程脚本为:
view plaincopy to clipboardprint?
--包
create or replace
PACKAGE DESKTOP_TEXTLIST_PACKAGE AS
TYPE T_CURSOR IS REF CURSOR;
--CrudAction:0:增;1:读;2:改;3:删;
--IOFields:查、改的字段列表字符串,使用分号分隔
--OrderBys:排序字段
--PageNo:页码
--PageSize:每页记录数
--RecordTotal:总记录数
--RecordSet:返回记录集
procedure DesktopTextListStorer (CrudAction IN INTEGER, fldUserCode IN NVARCHAR2, fldContent IN NCLOB, IOFields IN NVARCHAR2, OrderBys IN NVARCHAR2, PageNo IN INTEGER, PageSize IN INTEGER, RecordTotal OUT NUMBER, RecordSet IN OUT T_CURSOR);
END DESKTOP_TEXTLIST_PACKAGE;
--包体:
create or replace
PACKAGE BODY DESKTOP_TEXTLIST_PACKAGE AS
strFields VARCHAR2 (4000);
strOrderBys VARCHAR2 (4000);
strJoin VARCHAR2 (10);
strCond VARCHAR2 (4000);
strLike VARCHAR2 (500);
strWhere VARCHAR2 (10);
strAnd VARCHAR2 (10);
strSQLCalc VARCHAR2 (4000);
strSQLView VARCHAR2 (4000);
strEscape VARCHAR2 (500);
--CrudAction:0:增;1:读;2:改;3:删;
procedure DesktopTextListStorer (CrudAction IN INTEGER, fldUserCode IN NVARCHAR2, fldContent IN NCLOB, IOFields IN NVARCHAR2, OrderBys IN NVARCHAR2, PageNo IN INTEGER, PageSize IN INTEGER, RecordTotal OUT NUMBER, RecordSet IN OUT T_CURSOR) AS
BEGIN
RecordTotal := 0;
IF CrudAction < 0 OR CrudAction > 3 OR CrudAction IS NULL THEN
RETURN;
END IF;
IF CrudAction = 0 THEN
INSERT INTO DESKTOP_TEXTLIST ("USERCODE", "CONTENT")
VALUES (fldUserCode, fldContent);
RETURN;
END IF;
IF CrudAction = 2 then
IF IOFields IS NULL THEN
UPDATE DESKTOP_TEXTLIST
SET "CONTENT" = FLDCONTENT,
"FUNCODE" = FLDFUNCODE
WHERE "USERCODE" = fldUserCode;
ELSE
strCond := ',' + IOFields + ',';
strCond := REPLACE (strCond, ',USERCODE,', ',USERCODE=' || fldUserCode || ',');
strSQLView := 'UPDATE DESKTOP_PAGE'
|| ' SET ' || strCond
|| ' WHERE USERCODE=''' || fldUserCode || ''';
EXECUTE IMMEDIATE strSQLView;
IF INSTR (IOFIELDS, ',CONTENT,') > 0 THEN
UPDATE DESKTOP_TEXTLIST
SET "CONTENT" = fldContent
WHERE "USERCODE" = FLDUSERCODE;
END IF;
END IF;
RETURN;
END IF;
strCond := NULL;
strJoin := NULL;
strEscape := 'ESCAPE CHR (92 USING NCHAR_CS)';
IF fldUserCode IS NOT NULL THEN
strCond := strCond || strJoin || ' USERCODE = ''' || REPLACE (fldUserCode, '''', '''''') || '''';
strJoin := ' AND';
END IF;
IF FLDCONTENT IS NOT NULL THEN
strLike := REPLACE (fldContent, '''', '''''');
strCond := strCond || strJoin || ' DBMS_LOB.INSTR (CONTENT, ''' || strLike || ''') > 0';
strJoin := ' AND';
END IF;
IF strCond IS NULL THEN
strWhere := '';
strAnd := '';
ELSE
strWhere := ' WHERE';
strAnd := ' AND';
END IF;
IF CrudAction = 1 THEN
IF IOFields IS NULL THEN
strFields := 'DESKTOP_TEXTLIST.*';
ELSE
strFields := IOFields;
END IF;
IF OrderBys IS NULL THEN
strOrderBys := 'USERCODE, PAGECODE, FUNCODE';
ELSE
strOrderBys := REPLACE (OrderBys, ':0', '');
strOrderBys := REPLACE (strOrderBys, ':1', ' DESC');
END IF;
strSQLCalc := 'SELECT COUNT(*)'
|| ' FROM DESKTOP_TEXTLIST'
|| STRWHERE || STRCOND;
EXECUTE IMMEDIATE strSQLCalc INTO RecordTotal;
IF PageNo IS NULL THEN
strSQLView := 'SELECT ' || strFields
|| ' FROM DESKTOP_TEXTLIST'
|| strWhere || strCond
|| ' ORDER BY ' || strOrderBys;
ELSE
strSQLView := 'SELECT * FROM ('
|| ' SELECT ' || strFields || ', rownum rn FROM DESKTOP_TEXTLIST'
|| ' WHERE rownum <= ' || (PageSize * PageNo)
|| ' ORDER BY ' || strOrderBys || ')'
|| ' WHERE rn >= ' || (PageSize * (PageNo -1))
|| strAnd || strCond
|| ' ORDER BY ' || strOrderBys;
END IF;
OPEN RecordSet FOR strSQLView;
return;
ELSE
strSQLView := 'DELETE DESKTOP_TEXTLIST'
|| strWhere || strCond;
EXECUTE IMMEDIATE strSQLView;
END IF;
END DesktopTextListStorer;
END DESKTOP_TEXTLIST_PACKAGE;
--包
create or replace
PACKAGE DESKTOP_TEXTLIST_PACKAGE AS
TYPE T_CURSOR IS REF CURSOR;
--CrudAction:0:增;1:读;2:改;3:删;
--IOFields:查、改的字段列表字符串,使用分号分隔
--OrderBys:排序字段
--PageNo:页码
--PageSize:每页记录数
--RecordTotal:总记录数
--RecordSet:返回记录集
procedure DesktopTextListStorer (CrudAction IN INTEGER, fldUserCode IN NVARCHAR2, fldContent IN NCLOB, IOFields IN NVARCHAR2, OrderBys IN NVARCHAR2, PageNo IN INTEGER, PageSize IN INTEGER, RecordTotal OUT NUMBER, RecordSet IN OUT T_CURSOR);
END DESKTOP_TEXTLIST_PACKAGE;
--包体:
create or replace
PACKAGE BODY DESKTOP_TEXTLIST_PACKAGE AS
strFields VARCHAR2 (4000);
strOrderBys VARCHAR2 (4000);
strJoin VARCHAR2 (10);
strCond VARCHAR2 (4000);
strLike VARCHAR2 (500);
strWhere VARCHAR2 (10);
strAnd VARCHAR2 (10);
strSQLCalc VARCHAR2 (4000);
strSQLView VARCHAR2 (4000);
strEscape VARCHAR2 (500);
--CrudAction:0:增;1:读;2:改;3:删;
procedure DesktopTextListStorer (CrudAction IN INTEGER, fldUserCode IN NVARCHAR2, fldContent IN NCLOB, IOFields IN NVARCHAR2, OrderBys IN NVARCHAR2, PageNo IN INTEGER, PageSize IN INTEGER, RecordTotal OUT NUMBER, RecordSet IN OUT T_CURSOR) AS
BEGIN
RecordTotal := 0;
IF CrudAction < 0 OR CrudAction > 3 OR CrudAction IS NULL THEN
RETURN;
END IF;
IF CrudAction = 0 THEN
INSERT INTO DESKTOP_TEXTLIST ("USERCODE", "CONTENT")
VALUES (fldUserCode, fldContent);
RETURN;
END IF;
IF CrudAction = 2 then
IF IOFields IS NULL THEN
UPDATE DESKTOP_TEXTLIST
SET "CONTENT" = FLDCONTENT,
"FUNCODE" = FLDFUNCODE
WHERE "USERCODE" = fldUserCode;
ELSE
strCond := ',' + IOFields + ',';
strCond := REPLACE (strCond, ',USERCODE,', ',USERCODE=' || fldUserCode || ',');
strSQLView := 'UPDATE DESKTOP_PAGE'
|| ' SET ' || strCond
|| ' WHERE USERCODE=''' || fldUserCode || ''';
EXECUTE IMMEDIATE strSQLView;
IF INSTR (IOFIELDS, ',CONTENT,') > 0 THEN
UPDATE DESKTOP_TEXTLIST
SET "CONTENT" = fldContent
WHERE "USERCODE" = FLDUSERCODE;
END IF;
END IF;
RETURN;
END IF;
strCond := NULL;
strJoin := NULL;
strEscape := 'ESCAPE CHR (92 USING NCHAR_CS)';
IF fldUserCode IS NOT NULL THEN
strCond := strCond || strJoin || ' USERCODE = ''' || REPLACE (fldUserCode, '''', '''''') || '''';
strJoin := ' AND';
END IF;
IF FLDCONTENT IS NOT NULL THEN
strLike := REPLACE (fldContent, '''', '''''');
strCond := strCond || strJoin || ' DBMS_LOB.INSTR (CONTENT, ''' || strLike || ''') > 0';
strJoin := ' AND';
END IF;
IF strCond IS NULL THEN
strWhere := '';
strAnd := '';
ELSE
strWhere := ' WHERE';
strAnd := ' AND';
END IF;
IF CrudAction = 1 THEN
IF IOFields IS NULL THEN
strFields := 'DESKTOP_TEXTLIST.*';
ELSE
strFields := IOFields;
END IF;
IF OrderBys IS NULL THEN
strOrderBys := 'USERCODE, PAGECODE, FUNCODE';
ELSE
strOrderBys := REPLACE (OrderBys, ':0', '');
strOrderBys := REPLACE (strOrderBys, ':1', ' DESC');
END IF;
strSQLCalc := 'SELECT COUNT(*)'
|| ' FROM DESKTOP_TEXTLIST'
|| STRWHERE || STRCOND;
EXECUTE IMMEDIATE strSQLCalc INTO RecordTotal;
IF PageNo IS NULL THEN
strSQLView := 'SELECT ' || strFields
|| ' FROM DESKTOP_TEXTLIST'
|| strWhere || strCond
|| ' ORDER BY ' || strOrderBys;
ELSE
strSQLView := 'SELECT * FROM ('
|| ' SELECT ' || strFields || ', rownum rn FROM DESKTOP_TEXTLIST'
|| ' WHERE rownum <= ' || (PageSize * PageNo)
|| ' ORDER BY ' || strOrderBys || ')'
|| ' WHERE rn >= ' || (PageSize * (PageNo -1))
|| strAnd || strCond
|| ' ORDER BY ' || strOrderBys;
END IF;
OPEN RecordSet FOR strSQLView;
return;
ELSE
strSQLView := 'DELETE DESKTOP_TEXTLIST'
|| strWhere || strCond;
EXECUTE IMMEDIATE strSQLView;
END IF;
END DesktopTextListStorer;
END DESKTOP_TEXTLIST_PACKAGE;
四、对特殊字符的查询,如查询文本中是否包含“%”、“\”、“’”、“_”等符号;
Oracle脚本:
view plaincopy to clipboardprint?
strEscape := 'ESCAPE CHR (92 USING NCHAR_CS)';
strLike := REPLACE (fldPageName, '%', '\%');
STRLIKE := REPLACE (STRLIKE, '_', '\_');
strLike := REPLACE (strLike, '\', '\\');
strLike := REPLACE (strLike, '''', '''''');
strCond := strCond || strJoin || ' PAGENAME LIKE ''%' || strLike || '%'' ' || strEscape;
strEscape := 'ESCAPE CHR (92 USING NCHAR_CS)';
strLike := REPLACE (fldPageName, '%', '\%');
STRLIKE := REPLACE (STRLIKE, '_', '\_');
strLike := REPLACE (strLike, '\', '\\');
strLike := REPLACE (strLike, '''', '''''');
strCond := strCond || strJoin || ' PAGENAME LIKE ''%' || strLike || '%'' ' || strEscape;
以上是笔者操作Oracle数据库总结出来的一些经验,然后对大家有所帮助。s
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/cuizm/archive/2011/06/07/6528869.aspx
oracle表的历史数据转储过程,C#连接Oracle数据库通过存储过程操作数据库 - cuizm的专栏 - CSDN博客...相关推荐
- c 连接oracle数据库字符串,C#数据库连接字符串 - 水泛舟的专栏 - CSDN博客
C#数据库连接字符串 在MSDN中,.net的数据库连接字符串都有详细的说明,我这里以代码范例的方式罗列一些,具体的每一项代表的意义可以参看MSDN. ADO.net 中数据库连接方式(微软提供) 微 ...
- mysql 多表关联建模_(四)多对多模式 - 数据库模型设计专栏 - CSDN博客
连载之5 原创:胖子刘(转载请注明出处及作者,谢谢.)(四)多对多模式 多对多模式,也是比较常见的一种数据库设计模式,它所描述的两个对象不分主次.地位对等.互为一对多的关系.对于A表来说,一条记录对应 ...
- r如何连接oracle,R语言 R两种方式连接Oracle
关注微信公共号:小程在线 关注CSDN博客:程志伟的博客 一.通过RODBC包连接oracle 1.首先在本机找到ODBC数据源,点击添加,按照自己的oracle,填写下面三个位置 2.填写完之后,点 ...
- ubuntu 安装Pangolin 过程_余辉亮的学习笔记的博客-CSDN博客_pangolin安装
ubuntu 安装Pangolin 过程_余辉亮的学习笔记的博客-CSDN博客_pangolin安装
- 无人驾驶运动学模型——线性时变模型预测控制的思路推演过程_百叶书的博客-CSDN博客_线性时变模型预测控制 转
无人驾驶运动学模型--线性时变模型预测控制的思路推演过程_百叶书的博客-CSDN博客_线性时变模型预测控制
- pl/sql远程连接oracle服务器问题(各种情况) .,plsql远程连接oracle服务器问题(各种情况).docx...
plsql远程连接oracle服务器问题(各种情况).docx PLSQL远程连接oracle服务器问题(各种情况)1.病毒软件的防火墙可以关闭试试在连接.2.环境变量path里面没有加上%ORACL ...
- laravel框架连接Oracle,laravel5.8(十四)连接oracle数据库
首先确定你的PHP已经支持oracle数据库的链接.PHP需要安装OCI8扩展. 确定PHP可以链接ORACLE数据库之后.我们使用composer安装laravel支持oracle链接的插件 yaj ...
- oracle 表的er图,用PowerDesingner把oracle中的表导成er图
用PowerDesingner把oracle中的表导成er图 通过windows数据源管理,建立ODBC数据源. 我的是基于oracle10g. 打开Windows的控制面板 打开管理工具 打开数据源 ...
- navcat设置oracle表主键自增_初识 Oracle 表空间设置与管理
本文出自头条号老王谈运维,转载请说明出处. 前言 表空间是 Oracle 特有的一种逻辑结构,是管理和组织 Oracle 数据文件一种方式,一个Oracle 数据库能够有一个或多个表空间,而一个表空间 ...
最新文章
- 如何发布Node模块到NPM社区
- Oracle开发常用函数与存储过程
- 程序与进程的区别,并发与并行的区别,多进程的实现原理
- 实在不好意思,最近写个项目,一直没时间来灌水
- Python取出两个文件中相同的电话号码及地址(文件类型为:txt文本)
- 福昕阅读器drm加密解密总结
- 是否要运行此应用程序_使用Delve调试Go应用程序
- 定时器中断实验 编写程序使定时器0或者定时器1工作在方式2,自动重装载模式,定时500ms使两位数码管从00、01、02……98、99每间隔500ms加1显示。
- Unity同一项目双开方法
- 如何在恢复模式下启动 Mac?
- fixed定位之后,如何让div上下垂直居中
- 怎樣制作线段动画_几何画板如何做动画,看完明白了
- Windows7不再卡五叶草,更新了bootx64.efi和bootmgfw.efi文件,支持安全启动,不用关闭安全启动和打开csm支持.
- 最新 2022维达纸业AI面试真题题库
- CMakeLists.txt范例
- 自定义桌面右键菜单-Win 10 版
- 操作系统MSXML组件版本过低,导致启动失败的原因
- [zz]美团点评智能支付核心交易系统的可用性实践
- 微信小程序消息订阅超详细流程步骤
- Servlet报错500的问题
热门文章
- button Show most popular product
- nodejs里fs.readFile的相对路径转绝对路径问题
- WordPress的nocache header生成原理
- 解决function id unknown issue
- SAP Fiori gateway OData开发重要的tcode SEGW背后的数据库表
- 英语采访问题之:你每天上班的动机是什么?
- 从Wiesloch火车站到SAP Walldorf总部的交通方式
- 关于SAP Fiori Smart Template开发的一些实际例子
- mysql主从复制深入研究_mysql主从复制原理,深入探讨
- 职高计算机自我鉴定800字,中专生自我鉴定800字与中专生计算机专业自我鉴定汇编...