存储过程编写及C#调用

1.首先,我需要一张基础表

-- 创建学生表,用于测试,不讲究
create table XUESHENG
(
  id        INTEGER,
  xing_ming VARCHAR2(25),
  yu_wen    NUMBER,
  shu_xue   NUMBER
);

2.给里边插入插入数据若干条

insert into XUESHENG (ID, XING_MING, YU_WEN, SHU_XUE)values (1, 'zhangsan', 70, 70);
insert into XUESHENG (ID, XING_MING, YU_WEN, SHU_XUE)values (2, 'lisi', 80, 80);
insert into XUESHENG (ID, XING_MING, YU_WEN, SHU_XUE)values (3, 'wangwu', 90, 90);

3.1创建一个最简单的,没有传入参数,没有传出参数,没有返回值的存储过程

create or replace procedure proc_xuesheng_insert is
begin
  insert into xuesheng values (4, 'maliu', 90, 90);
  commit;
end proc_xuesheng_insert;
exec proc_xuesheng_insert

  


//将马六的成绩插入表
int i = OracleHelper.ExcuteProcedureWithNoParameter(iniConnString, "proc_xuesheng_insert");


/// <summary>
        /// 执行 无参数 的存储过程
        /// </summary>
        /// <param name="connString">连接字符串</param>
        /// <param name="proceducreName">存储过程名</param>
        /// <returns>影响的条数</returns>
        public static int ExcuteProcedureWithNoParameter(string connString, string proceducreName)
        {
            int i = -1;
            using (OracleConnection oc = new OracleConnection(connString))
            {
                try
                {
                    oc.Open();
                    OracleCommand cmd = oc.CreateCommand();
                    cmd.CommandType = CommandType.StoredProcedure;//指明是执行存储过程
                    cmd.CommandText = proceducreName;
                    i = cmd.ExecuteNonQuery();
                    oc.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "存储过程调用错误", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                }
                finally
                {
                    oc.Close();
                }
            }
            return i;
        }

 

 3.2创建一个有传入值的存储过程

create or replace procedure proc_xuesheng_yuwen_add(
temp_name in varchar2,--要改分数的学生名
temp_num in number--要加多少分
) 
is
begin
  update xuesheng set xuesheng.yu_wen=xuesheng.yu_wen+temp_num where temp_name=xuesheng.xing_ming;
  commit;
end;
exec proc_xuesheng_yuwen_add('zhangsan',3)

 


//将xx学生的语文分数加i分
int j = OracleHelper.ExcuteProcedureWithOnlyParameterIn(iniConnString, "proc_xuesheng_score_add","lisi",1);


///
<summary> /// 执行只有输入字段内容的 /// </summary> /// <param name="connString">连接字符串</param> /// <param name="proceducreName">存储过程名</param> /// <param name="studentName">学生名称</param> /// <param name="scoreNeed2Add">加分数</param> /// <returns></returns> public static int ExcuteProcedureWithOnlyParameterIn(string connString, string proceducreName, string studentName, int scoreNeed2Add) { int i = -1; using (OracleConnection oc = new OracleConnection(connString)) { try { oc.Open(); OracleCommand cmd = oc.CreateCommand(); cmd.CommandType = CommandType.StoredProcedure;//指明是执行存储过程 cmd.CommandText = proceducreName; cmd.Parameters.Add(new OracleParameter() { ParameterName = "TEMP_NAME", Value = studentName, OracleDbType = OracleDbType.Varchar2, Size = 20, Direction = ParameterDirection.Input }); cmd.Parameters.Add(new OracleParameter() { ParameterName = "TEMP_NUM", Value = scoreNeed2Add, OracleDbType = OracleDbType.Int32, Size = 8, Direction = ParameterDirection.Input }); i = cmd.ExecuteNonQuery(); oc.Close(); } catch (Exception ex) { MessageBox.Show(ex.Message, "存储过程调用错误", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); } finally { oc.Close(); } } return i; }

 

 

程序写到这里发现了一个问题:

如果调用的过程涉及到参数的话,就需要从外部按照顺序构造参数OracleParameter[],然后传进来即可。

 

 //用参数话的方法,把只有输入值的内容传出来
            OracleParameter[] ops = {
                new OracleParameter() { ParameterName = "TEMP_NAME", Value = "lisi", OracleDbType = OracleDbType.Varchar2, Size = 20, Direction = ParameterDirection.Input },
                new OracleParameter() { ParameterName = "TEMP_NUM", Value = 1, OracleDbType = OracleDbType.Int32, Size = 8, Direction = ParameterDirection.Input }
            };
            int jj = OracleHelper.ExcuteProcedureWithOnlyParameterIn2(iniConnString, "proc_xuesheng_score_add", ops);


/// <summary>
        /// 执行只有输入字段内容的
        /// </summary>
        /// <param name="connString">连接字符串</param>
        /// <param name="proceducreName">存储过程名</param>
        /// <param name="ops">参数列表</param>
/// <returns></returns> public static int ExcuteProcedureWithOnlyParameterIn2(string connString, string proceducreName,OracleParameter[] ops) { int i = -1; using (OracleConnection oc = new OracleConnection(connString)) { try { oc.Open(); OracleCommand cmd = oc.CreateCommand(); cmd.CommandType = CommandType.StoredProcedure;//指明是执行存储过程 cmd.CommandText = proceducreName; foreach (var op in ops) { cmd.Parameters.Add(op); } i = cmd.ExecuteNonQuery(); oc.Close(); } catch (Exception ex) { MessageBox.Show(ex.Message, "存储过程调用错误", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); } finally { oc.Close(); } } return i; }

 

 

 3.3创建一个有传入值传出值的存储过程

create or replace procedure proc_xuesheng_totalScore(
temp_name in varchar2,
temp_num  out number) is
  num_1 number;
  num_2 number;
begin
  select yu_wen, shu_xue
    into num_1, num_2
    from xuesheng
   where xing_ming = temp_name;
  --dbms_output.put_line(num_1 + num_2);
  temp_num := num_1 + num_2;
end;
var temp_num number
exec proc_xuesheng_totalScore('wangwu',:temp_num)

PL/SQL procedure successfully completed

temp_num
---------
180

int sumScore = -1;
OracleHelper.ExcuteProcedureWithParameterInOut(iniConnString, "proc_xuesheng_totalScore","lisi", out sumScore);

MessageBox.Show(sumScore.ToString());



/// <summary> /// 执行有输入输出的 /// </summary> /// <param name="connString">连接字符串</param> /// <param name="proceducreName">存储过程名</param> /// <param name="studentName">学生名称</param> /// <param name="sumScore">语文数学分数合计</param> /// <returns></returns> public static int ExcuteProcedureWithParameterInOut(string connString, string proceducreName, string studentName, out int sumScore) { int i = -1; sumScore = -1; using (OracleConnection oc = new OracleConnection(connString)) { try { oc.Open(); OracleCommand cmd = oc.CreateCommand(); cmd.CommandType = CommandType.StoredProcedure;//指明是执行存储过程 cmd.CommandText = proceducreName; OracleParameter[] parameters = { new OracleParameter() { ParameterName = "TEMP_NAME", Value = studentName, OracleDbType = OracleDbType.Varchar2, Size = 20, Direction = ParameterDirection.Input }, new OracleParameter() { ParameterName = "TEMP_NUM", Value = null, OracleDbType = OracleDbType.Int32, Size = 8, Direction = ParameterDirection.Output } }; foreach (var x in parameters) { cmd.Parameters.Add(x); } i = cmd.ExecuteNonQuery(); sumScore = int.Parse(cmd.Parameters[1].Value.ToString()); oc.Close(); } catch (Exception ex) { MessageBox.Show(ex.Message, "存储过程调用错误", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); } finally { oc.Close(); } } return i; }

 

这个方法写出来,不太爽,因为需要在方法内构造这个存储过程,需要将他外置到具体这个存储的需求端

   int temp_num=-1;
            OracleParameter[] ops = {
                new OracleParameter() { ParameterName = "TEMP_NAME", Value = "lisi", OracleDbType = OracleDbType.Varchar2, Size = 20, Direction = ParameterDirection.Input },
                new OracleParameter() { ParameterName = "TEMP_NUM", Value = null, OracleDbType = OracleDbType.Int32, Size = 8, Direction = ParameterDirection.Output }
            };
            ops = OracleHelper.ExcuteProcedureWithParameterInOut2(iniConnString, "proc_xuesheng_totalScore", ops);
            foreach (OracleParameter op in ops)
            {
                if (op.Direction == ParameterDirection.Output)
                {
                    if (op.ParameterName == "TEMP_NUM")
                        temp_num = int.Parse(op.Value.ToString());
                }
            }
            MessageBox.Show(temp_num.ToString());




        /// <summary>
        /// 执行有输入输出的
        /// </summary>
        /// <param name="connString">连接字符串</param>
        /// <param name="proceducreName">存储过程名</param>
        /// <param name="ops">Oracle参数列表</param>
        /// <returns>赋值过output内容后的Oracle参数列表</returns>
        public static OracleParameter[] ExcuteProcedureWithParameterInOut2(string connString, string proceducreName, OracleParameter[] ops)
        {
            using (OracleConnection oc = new OracleConnection(connString))
            {
                try
                {
                    oc.Open();
                    OracleCommand cmd = oc.CreateCommand();
                    cmd.CommandType = CommandType.StoredProcedure;//指明是执行存储过程
                    cmd.CommandText = proceducreName;
                    foreach (var op in ops)
                        cmd.Parameters.Add(op); 
                    cmd.ExecuteNonQuery();

                    for (int i = 0; i < ops.Length; i++)
                    {
                        ops[i] = cmd.Parameters[i];
                    }
                    oc.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "存储过程调用错误", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                }
                finally
                {
                    oc.Close();
                }
            }
            return ops;
        }

 

 大功告成,今天开始工作时,自己只是个存储过程,没超过10行的小白,今天能完成这么多工作还是很欣喜的。 

posted @ 2020-02-20 14:53  一年变大牛  阅读(522)  评论(0编辑  收藏  举报