浅谈PetShop之使用存储过程与PLSQL批量处理(附案例)
1 大概思路

备注:黄色为影响参数
2 PetShop4的经典数据库连接代码回顾
PetShop4有3个函数,具体有:
ExecuteReader:可以读一个表的记录,只能读不能写。
ExecuteScalar:只能读一条记录,一般用来判断数据库是否有数据等,只能读不能写。
ExecuteNonQuery:可以写以可以读。
这里介绍一下PrepareCommand、ExecuteNoQuery。
2.1 PrepareCommand
注意:当前函数是private的,不提供给外部调用。
/// <summary> /// Internal function to prepare a command for execution by the database /// </summary> /// <param name="cmd">Existing command object</param> /// <param name="conn">Database connection object</param> /// <param name="trans">Optional transaction object</param> /// <param name="cmdType">Command type, e.g. stored procedure</param> /// <param name="cmdText">Command test</param> /// <param name="commandParameters">Parameters for the command</param> private static void PrepareCommand(OracleCommand cmd, OracleConnection conn, OracleTransaction trans, CommandType cmdType, string cmdText, OracleParameter[] commandParameters) { //Open the connection if required if (conn.State != ConnectionState.Open) conn.Open(); //Set up the command cmd.Connection = conn; cmd.CommandText = cmdText; cmd.CommandType = cmdType; //Bind it to the transaction if it exists if (trans != null) cmd.Transaction = trans; // Bind the parameters passed in if (commandParameters != null) { foreach (OracleParameter parm in commandParameters) cmd.Parameters.Add(parm); } }
2.2 ExecuteNoQuery
此函数:传入连接串、执行类型、SQL、参数
/// <summary> /// Execute a database query which does not include a select /// </summary> /// <param name="connString">Connection string to database</param> /// <param name="cmdType">Command type either stored procedure or SQL</param> /// <param name="cmdText">Acutall SQL Command</param> /// <param name="commandParameters">Parameters to bind to the command</param> /// <returns></returns> public static int ExecuteNonQuery(string connectionString, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) { // Create a new Oracle command OracleCommand cmd = new OracleCommand(); //Create a connection using (OracleConnection connection = new OracleConnection(connectionString)) { //Prepare the command PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters); //Execute the command int val = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return val; } }
此函数:传入事务、执行类型、SQL、参数
/// <summary> /// Execute an OracleCommand (that returns no resultset) against an existing database transaction /// using the provided parameters. /// </summary> /// <remarks> /// e.g.: /// int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders", new OracleParameter(":prodid", 24)); /// </remarks> /// <param name="trans">an existing database transaction</param> /// <param name="commandType">the CommandType (stored procedure, text, etc.)</param> /// <param name="commandText">the stored procedure name or PL/SQL command</param> /// <param name="commandParameters">an array of OracleParamters used to execute the command</param> /// <returns>an int representing the number of rows affected by the command</returns> public static int ExecuteNonQuery(OracleTransaction trans, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) { OracleCommand cmd = new OracleCommand(); PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, commandParameters); int val = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return val; }
此函数:传入连接、执行类型、SQL、参数
/// <summary> /// Execute an OracleCommand (that returns no resultset) against an existing database connection /// using the provided parameters. /// </summary> /// <remarks> /// e.g.: /// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new OracleParameter(":prodid", 24)); /// </remarks> /// <param name="conn">an existing database connection</param> /// <param name="commandType">the CommandType (stored procedure, text, etc.)</param> /// <param name="commandText">the stored procedure name or PL/SQL command</param> /// <param name="commandParameters">an array of OracleParamters used to execute the command</param> /// <returns>an int representing the number of rows affected by the command</returns> public static int ExecuteNonQuery(OracleConnection connection, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) { OracleCommand cmd = new OracleCommand(); PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters); int val = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return val; }
3 如何写好一个的OracleHelper
3.1 PetShop的OracleHelper
PetShop不是写好了吗?为什么还要自己写?
eg:PetShop4的函数不足以方便我们操作数据库,如批量插入需要防注入的参数时,需要等全部插入完再提交整个事务。
eg:PetShop4的函数在处理存储过程里还不完善,返回值没有指向。
3.2 OracleHelper
注意:PetShop4在参数上在调用OracleHelper考虑了缓存,这里暂时不考虑。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data;using System.Data.OracleClient;using System.Collections;namespace Util{ public abstract class OracleHelper { /// <summary> /// 准备存储过程执行查询 /// </summary> /// <param name="connectionString">数据库连接</param> public static OracleTransaction GetTrans(string connectionString) { OracleConnection conn = new OracleConnection(connectionString); conn.Open(); OracleTransaction trans = conn.BeginTransaction(); return trans; } /// <summary> /// 返回视图 /// </summary> /// <param name="cmdType"></param> /// <param name="cmdText"></param> /// <param name="commandParameters"></param> /// <returns></returns> public static DataView ExecuteView(String connectionString, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) { OracleCommand cmd = new OracleCommand(); using (OracleConnection conn = new OracleConnection(connectionString)) { PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters); DataSet ds = new DataSet(); OracleDataAdapter da = new OracleDataAdapter(cmd); da.Fill(ds); DataView dv = ds.Tables[0].DefaultView; cmd.Parameters.Clear(); return dv; } } /// <summary> /// 执行并返回影响行数 /// </summary> /// <param name="connectionString">连接字符串</param> /// <param name="cmdType">执行类型</param> /// <param name="cmdText">执行文本</param> /// <param name="commandParameters">参数</param> /// <returns></returns> public static int ExecuteNonQuery(string connectionString, CommandType cmdType, string cmdText, IList commandParameters) { OracleCommand cmd = new OracleCommand(); using (OracleConnection connection = new OracleConnection(connectionString)) { PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters); int val = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return val; } } /// <summary> /// Execute a database query which does not include a select /// </summary> /// <param name="connString">Connection string to database</param> /// <param name="cmdType">Command type either stored procedure or SQL</param> /// <param name="cmdText">Acutall SQL Command</param> /// <param name="commandParameters">Parameters to bind to the command</param> /// <returns></returns> public static int ExecuteNonQuery(string connectionString, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) { // Create a new Oracle command OracleCommand cmd = new OracleCommand(); //Create a connection using (OracleConnection connection = new OracleConnection(connectionString)) { //Prepare the command PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters); //Execute the command int val = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return val; } } /// <summary> /// Execute a OracleCommand (that returns a 1x1 resultset) against the specified SqlTransaction /// using the provided parameters. /// </summary> /// <param name="transaction">A valid SqlTransaction</param> /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param> /// <param name="commandText">The stored procedure name or PL/SQL command</param> /// <param name="commandParameters">An array of OracleParamters used to execute the command</param> /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns> public static int ExecuteNonQuery(OracleTransaction trans, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) { OracleCommand cmd = new OracleCommand(); PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, commandParameters); int val = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return val; } /// <summary> /// 执行并返回影响行数,得手动关闭数据库连接 /// </summary> /// <param name="connection">连接字符串</param> /// <param name="cmdType">执行类型</param> /// <param name="cmdText">执行文本</param> /// <param name="commandParameters">参数</param> /// <returns></returns> public static int ExecuteNonQuery(OracleConnection connection, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) { OracleCommand cmd = new OracleCommand(); PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters); int val = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return val; } /// <summary> /// Execute a select query that will return a result set /// </summary> /// <param name="connString">Connection string</param> //// <param name="commandType">the CommandType (stored procedure, text, etc.)</param> /// <param name="commandText">the stored procedure name or PL/SQL command</param> /// <param name="commandParameters">an array of OracleParamters used to execute the command</param> /// <returns></returns> public static OracleDataReader ExecuteReader(string connectionString, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) { //Create the command and connection OracleCommand cmd = new OracleCommand(); OracleConnection conn = new OracleConnection(connectionString); try { //Prepare the command to execute PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters); //Execute the query, stating that the connection should close when the resulting datareader has been read OracleDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection); cmd.Parameters.Clear(); return rdr; } catch { //If an error occurs close the connection as the reader will not be used and we expect it to close the connection conn.Close(); throw; } } /// <summary> /// Internal function to prepare a command for execution by the database /// </summary> /// <param name="cmd">Existing command object</param> /// <param name="conn">Database connection object</param> /// <param name="trans">Optional transaction object</param> /// <param name="cmdType">Command type, e.g. stored procedure</param> /// <param name="cmdText">Command test</param> /// <param name="commandParameters">Parameters for the command</param> private static void PrepareCommand(OracleCommand cmd, OracleConnection conn, OracleTransaction trans, CommandType cmdType, string cmdText, OracleParameter[] commandParameters) { //Open the connection if required if (conn.State != ConnectionState.Open) conn.Open(); //Set up the command cmd.Connection = conn; cmd.CommandText = cmdText; cmd.CommandType = cmdType; //Bind it to the transaction if it exists if (trans != null) cmd.Transaction = trans; // Bind the parameters passed in if (commandParameters != null) { // 若参数Value值为null时,插入到数据库的值应该为DBNull.Value,且为ParameterDirection.Input foreach (OracleParameter parm in commandParameters) if (parm.Value == null && parm.Direction == ParameterDirection.Input) { cmd.Parameters.Add(parm.ParameterName, parm.OracleType, parm.Size).Value = DBNull.Value; } else { cmd.Parameters.Add(parm); } } } /// <summary> /// Internal function to prepare a command for execution by the database /// </summary> /// <param name="cmd">Existing command object</param> /// <param name="conn">Database connection object</param> /// <param name="trans">Optional transaction object</param> /// <param name="cmdType">Command type, e.g. stored procedure</param> /// <param name="cmdText">Command test</param> /// <param name="commandParameters">Parameters for the command</param> private static void PrepareCommand(OracleCommand cmd, OracleConnection conn, OracleTransaction trans, CommandType cmdType, string cmdText, IList commandParameters) { //Open the connection if required if (conn.State != ConnectionState.Open) conn.Open(); //Set up the command cmd.Connection = conn; cmd.CommandText = cmdText; cmd.CommandType = cmdType; //Bind it to the transaction if it exists if (trans != null) cmd.Transaction = trans; // Bind the parameters passed in if (commandParameters != null) { // 若参数Value值为null时,插入到数据库的值应该为DBNull.Value,且为ParameterDirection.Input foreach (OracleParameter parm in commandParameters) if (parm.Value == null && parm.Direction == ParameterDirection.Input) { cmd.Parameters.Add(parm.ParameterName, parm.OracleType, parm.Size).Value = DBNull.Value; } else { cmd.Parameters.Add(parm); } } } }}
4 代码示例
4.1 使用存储过程
/// <summary> /// 新增 /// </summary> /// <param name="v_dept">实体</param> /// <param name="re">返回ID</param> /// <param name="msg">返回消息</param> /// <returns></returns> private void executeWithOracleTrans(DEPT v_dept, ref int re, ref string msg) { try { OracleParameter[] paras = new OracleParameter[5]; paras[0] = new OracleParameter("P_DEPTNO", OracleType.Number); paras[0].Value = v_dept.DEPTNO; paras[1] = new OracleParameter("P_DNAME", OracleType.VarChar); paras[1].Value = v_dept.DNAME; paras[2] = new OracleParameter("P_LOC", OracleType.VarChar); paras[2].Value = v_dept.LOC; paras[3] = new OracleParameter("X_RE", OracleType.Int32); paras[3].Direction = ParameterDirection.Output; paras[4] = new OracleParameter("X_MSG", OracleType.VarChar, 100); paras[4].Direction = ParameterDirection.Output; OracleHelper.ExecuteNonQuery(this.OracleConnectString, CommandType.StoredProcedure, "PKG_DEMO.Dept_Add", paras); re = Convert.ToInt32(paras[3].Value); msg = paras[4].Value.ToString(); } catch (Exception ex) { re = 9; msg = ex.Message; } }
4.2 批处理之使用PL/SQL
/// <summary> /// 用PL/SQL增加 /// </summary> /// <param name="list_dept"></param> /// <param name="re"></param> /// <param name="msg"></param> private void executeWithPLSQL(IList<DEPT> list_dept, ref int re, ref string msg) { string sql = string.Empty; string insert_sql = string.Empty; List<OracleParameter> list_parm = new List<OracleParameter>(); try { int i = 0; foreach (DEPT v_dept in list_dept) { insert_sql += "insert into DEPT (DEPTNO, DNAME, LOC) values(:P_DEPTNO" + i + ", :P_DNAME" + i + ", :P_LOC" + i + ");"; OracleParameter[] paras = new OracleParameter[3]; paras[0] = new OracleParameter("P_DEPTNO" + i, OracleType.Number); paras[0].Value = v_dept.DEPTNO; paras[1] = new OracleParameter("P_DNAME" + i, OracleType.VarChar); paras[1].Value = v_dept.DNAME; paras[2] = new OracleParameter("P_LOC" + i, OracleType.VarChar); paras[2].Value = v_dept.LOC; list_parm.Add(paras[0]); list_parm.Add(paras[1]); list_parm.Add(paras[2]); i++; } sql = "begin " + insert_sql + ":X_RE := 1; " + ":X_MSG := '提示:新增成功!'; " + "commit; " + "exception " + "when others then " + "rollback; " + ":X_RE := 9; " + ":X_MSG := '操作失败:[' || sqlcode || ':' || sqlerrm || ']'; " + "end; "; OracleParameter x_re = new OracleParameter("X_RE", OracleType.Int32); x_re.Direction = ParameterDirection.Output; OracleParameter x_msg = new OracleParameter("X_MSG", OracleType.VarChar, 100); x_msg.Direction = ParameterDirection.Output; list_parm.Add(x_re); list_parm.Add(x_msg); OracleHelper.ExecuteNonQuery(this.OracleConnectString, CommandType.Text, sql, list_parm); re = Convert.ToInt32(x_re.Value); msg = x_msg.Value.ToString(); } catch (Exception ex) { re = 9; msg = ex.Message; } }
4.3 批处理之使用事务
/// <summary> /// 用事务新增 /// </summary> /// <param name="list_dept"></param> /// <param name="re"></param> /// <param name="msg"></param> private void executeWithTrans(IList<DEPT> list_dept, ref int re, ref string msg) { // 启用事务进行控制 OracleTransaction myTrans = OracleHelper.GetTrans(this.OracleConnectString); OracleConnection conn = myTrans.Connection; try { string sql = string.Empty; foreach (DEPT o in list_dept) { sql = "insert into DEPT(DEPTNO,DNAME,LOC) values(:P_DEPTNO,:P_DNAME,:P_LOC)"; OracleParameter[] paras = new OracleParameter[3]; paras[0] = new OracleParameter("P_DEPTNO", OracleType.Int32); paras[0].Value = o.DEPTNO; paras[1] = new OracleParameter("P_DNAME", OracleType.VarChar); paras[1].Value = o.DNAME; paras[2] = new OracleParameter("P_LOC", OracleType.VarChar); paras[2].Value = o.LOC; OracleHelper.ExecuteNonQuery(myTrans, CommandType.Text, sql, paras); } myTrans.Commit(); re = 1; } catch (Exception ex) { myTrans.Rollback(); re = 9; msg = ex.Message; } finally { conn.Close(); } }
5 运行效果

6 小结
学好.Net,从PetShop开始。
浅谈PetShop之使用存储过程与PLSQL批量处理(附案例)的更多相关文章
- 浅谈Python内置对象类型——数字篇(附py2和py3的区别之一)
Python是一门面向对象的编程设计语言,程序中每一样东西都可以视为一个对象.Python内置对象可以分为简单类型和容器类型,简单类型主要是数值型数据,而容器类型是可以包含其他对象类型的集体,如序列. ...
- 浅谈SQL注入风险 - 一个Login拿下Server
前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...
- 浅谈SQL注入风险 - 一个Login拿下Server(转)
前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...
- 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载
浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- 浅谈c#的三个高级参数ref out 和Params C#中is与as的区别分析 “登陆”与“登录”有何区别 经典SQL语句大全(绝对的经典)
浅谈c#的三个高级参数ref out 和Params c#的三个高级参数ref out 和Params 前言:在我们学习c#基础的时候,我们会学习到c#的三个高级的参数,分别是out .ref 和 ...
- 浅谈 Fragment 生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...
- 浅谈 LayoutInflater
浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
随机推荐
- Linux下的ntp时钟同步问题
前段时间,项目中有个需求,需要将linux和windows的时间进行同步,网上也有很多类似时钟同步的帖子,大致类似:不过本次的linux的机器有点特殊,没有service命令,而且要求在另一台suse ...
- xml simpleXML_load_file(), simpleXML_load_string()
xml.xml文件 <?xml version='1.0'?><man> <att> <name>lin3615</name& ...
- DZ升级到X3.2后,UCenter用户管理中心进不了了
前天将DZ升级到X3.2后,UCenter用户管理中心进不了了,输入的密码也对,验证码也对,就是点登录后没反应,又回来输入前的状态.如果更换密码后,显示密码错误,证明密码是没错的.但就是进不了.大家看 ...
- Winform窗口弹出位置控制
窗体的弹出位置可以由属性StartPosition来指定,默认值有: Manural 自定义,由属性Location指定: CenterScreen 屏幕中央: WindowsDefaultBound ...
- thymeleaf 基本语法
四.标准表达式语法 · 简单表达式 (simple expressions) ${...} 变量表达式 *{...} 选择变量表达式 #{...} 消息表达式 @{...} 链接url表达式 ...
- 从Windows远程Ubuntu
关键字:Windows,Ubuntu,Putty,WinSCP OS:Windows 7,Ubuntu. 1.下载Putty:http://www.putty.org/. 2.双击运行putty.ex ...
- android实现视频图片取缩略图
取缩略图不等同于缩放图片. 缩放图片是保持不失真的情况下缩放处理,并进行平滑处理. 缩略图则不然,允许失真,目的只是取出图片的轮廓. 保存Bitmap图片 private void saveBitma ...
- Silverlight之我见
好长时间没搞Silverlight方面的开发了,原本都以为自己早已忘记,然而前阵子(确切一点说,是挺长时间以前了)的时候,发布Windows10的时候,微软宣布新的浏览器将重新开发,关键是后半句引起了 ...
- 洛谷 P1063 能量项链
题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定 ...
- 一般处理程序(ashx)和页面处理程序(aspx)的区别
客官请看图 图中的Httphandler就是处理程序. 两者的共同点 如果把aspx处理程序和ashx处理程序放到上图中,他们是处在相同的位置的, 他们都实现了IHttphandler接口.实 ...