分享

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

 昵称10504424 2013-03-04

目录

1       大概思路... 2

2       PetShop4的经典数据库连接代码回顾... 3

2.1        PrepareCommand. 3

2.2        ExecuteNoQuery. 4

3       如何写好一个的OracleHelper 5

3.1        PetShop的OracleHelper 5

3.2        OracleHelper 6

4       代码示例... 6

4.1        使用存储过程... 6

4.2        批处理之使用PL/SQL. 7

4.3        批处理之使用事务... 8

5       运行效果... 10

6       小结... 10

 

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开始。

源代码下载:

http://files.cnblogs.com/yongfeng/HowToConnectDataBase.rar

数据库存储过程下载:

http://files.cnblogs.com/yongfeng/Package.rar

PDF下载:

http://files.cnblogs.com/yongfeng/20130301.rar

录像下载:

http://files.cnblogs.com/yongfeng/Media.rar

 

 

博文分享:


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约