淺談PetShop之使用存儲過程與PLSQL批量處理(附案例)


目錄

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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM