优化上传导入名单模块之Oracle的存储过程简记

项目中要把号码名单(Excel,ACCESS,txt)导入Oracle数据库,以前只是用少量数据进行测试,一期项目上线后要求改进。

按照以前的代码的效率,5万条数据导下来要半小时,当然,里面有业务逻辑,需要每次从别的几张表中查询是否重复,并删除。

现在需求,20万条数据最多20分钟,于是,翻工重写。

我们的解决方案如下:

1、从每次插入1条数据变成每次向数据库插入1000条数据。2、编写存储过程,业务逻辑性的操作在存储过程中进行。3、利用多线程,让用户上传的时候可以做别的操作。

本篇文章先解决前两个内容。(当时我写此文章开头的时候,总监过来了,一番交流后,他建议我用ODP,100万条数据几秒钟搞定,当时我就感觉我们的方案弱爆了。。毕竟刚毕业的学生,不知道ODP,情有可原,情有可原。。害羞

一、废话少说,先解决每条sql语句向数据库插入1000条数据,代码如下:

  string sql = string.Empty;
                for (int i = 0; i < ds.Tables[0].Rows.Count; i += 1000)//一千个号码提交一次
                {
                    sql = string.Empty;
                    sql += "begin  ";//bengin后留个空格,没有分号
                    for (int j = i; j < i + 1000 && j < ds.Tables[0].Rows.Count; j++)
                    {
                        ele[0] = ds.Tables[0].Rows[j][selectnum].ToString();
                        ele[1] = ds.Tables[0].Rows[j][selectname].ToString();
                        if (flag[j] == false)
                        {
                            if (CheckBox1.Checked == false)//这个是选择框是否被选择,不选的话不导入姓名。
                            {
                                sql += string.Format("insert into KA_BlackList (telnum,telname,inserttime,listtype,companyid,departid,operid) values('{0}',null,sysdate,{1},null,{2},{3});", ele[0], "1", "1", session);
                            }
                            else
                            {

                                sql += string.Format("insert into KA_BlackList (telnum,telname,inserttime,listtype,companyid,departid,operid) values('{0}','{1}',sysdate,{2},null,{3},{4});", ele[0], ele[1], "1", "1", session);
                            }

                        }
                    }
                    sql += "  commit; end;";


以前没做过,其实语法很简单,注意begin后面没分号,C#语句写的时候begin后要加个空格隔开

begin

sql语句。。。;

sql语句。。。;

sql语句。。。;

commit;

end;


二、下面说一下oracle的存储过程

  1  CREATE OR REPLACE PROCEDURE 存储过程名(CREATE OR REPLACE PROCEDURE 是一个SQL语句通知Oracle数据库去创建一个存储过程, 如果存在就覆盖它;)

   IS或者AS(单独的FUNCTION, PROCEDURE 习惯用AS,PACKAGE 中的FUNCTION, PROCEDURE 用IS,功能基本一样,但需要指定的时候用IS

   BEGIN(这个也是没有分号!!

  4  NULL;(有sql语句就写sql语句,没有的话必须加NULL

   END;


下面是项目中的存储过程:

CREATE OR REPLACE Procedure KEYACCOUNT.KA_blacklist_Pro
(--这些是返回的参数。
  count1   out   number,--本表号码重复数
  count2   out   number,-- 白名单号码重复数
  count3   out   number --例外名单号码重复数

as--这些是定义的变量
 breforedel_count   number;--导入号码后,还没去重前的号码数
 afterdel_count    number;--去重后的号码数
 
begin

    select count(*) into breforedel_count  from KA_blacklist ;--查询出去重前的号码数
    
    delete from KA_blacklist a where  a.id!=(select min(id) from KA_blacklist b where a.telnum=b.telnum);--本表的去重
    select count(*) into  afterdel_count from KA_blacklist;--本表去重后的号码数
    count1:=breforedel_count-afterdel_count;--求出本表的重复数
   
    select count(*) into count2 from KA_blacklist where telnum in (select telnum from ka_whitelist);--查询与白名单的重复号码数
    delete KA_whitelist where telnum in (select telnum from ka_blacklist);--白名单的去重,即把白名单中与黑名单相同的号码删除
     
    select count(*) into count3 from KA_blacklist where telnum in (select telnum from ka_exceptlist);--查询与例外名单的重复号码数
    delete KA_exceptlist where telnum in (select telnum from ka_blacklist);--例外名单的去重,即把例外名单中与黑名单相同的号码删除

end;
/

 再写一下如何在C#中调用存储过程:

//定义三个出参

                OracleParameter[] pars = { new OracleParameter("count1", OracleType.Number), new OracleParameter("count2", OracleType.Number), new OracleParameter("count3", OracleType.Number) };
                pars[0].Direction = ParameterDirection.Output;
                pars[1].Direction = ParameterDirection.Output;
                pars[2].Direction = ParameterDirection.Output;

 

 //执行存储过程

 using (OracleConnection con = new OracleConnection(sConnectionString))
            {
                con.Open();
                OracleCommand cmd = new OracleCommand(存储过程名, con);
                if (pars!= null)
                {
                    foreach (OracleParameter par  in  pars)
                    {
                        cmd.Parameters.Add(par);
                    }
                }
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.ExecuteNonQuery();
                cmd.Dispose();

                con.close();

 

//定义变量,把出参的值赋给它们

                int a1 = ds.Tables[0].Rows.Count - int.Parse(pars[0].Value.ToString())-err;
                int a2 = int.Parse(pars[0].Value.ToString());
                int a3 = int.Parse(pars[1].Value.ToString());
                int a4 = int.Parse(pars[2].Value.ToString());
                Response.Write(string.Format("<script language = javascript>alert('成功导入{0}条,重复{1}条,错误{4}条。白名单存在{2}条已删除,例外名单存在{3}条已删除。');window.location = 'BlackList.aspx';</script>", a1.ToString(), a2.ToString(), a3.ToString(), a4.ToString(), err));
               

 

三、线程的问题就不写了,总监说了用ODP,上面的批量导入和线程就没用了。在B/S项目最好不要用线程,会出现很多问题。

以前5万条数据需要半小时,用批量导入加存储过程后不到20分钟。目前项目用的是ODP,一分钟不到就搞定!得意

不过在写ODP的时候也出现了一些问题,毕竟刚接触。下一篇文章中会写一下关于ODP的内容。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 等保2.0标准中对技术安全要求主要包括信息安全类要求(简记为x)、服务保证类要求(简记为s)、其他安全保护类要求(简记为g)和数据设备类要求(简记为f)。 a. 信息安全类要求(x)是等保2.0标准中的一项重要要求,它涉及了信息系统的安全保护、安全管理和信息安全技术的实施要求,包括身份认证、访问控制、审计、加密等内容。 b. 服务保证类要求(s)也是等保2.0标准中的一项重要要求,它主要围绕着信息系统的可用性、可靠性和稳定性进行要求,包括灾备备份、容灾恢复、业务连续性等内容。 c. 其他安全保护类要求(g)是等保2.0标准中的一项综合要求,主要涉及到对软硬件安全配置、网络安全和物理环境安全等方面的要求,包括网络隔离、漏洞修复、环境监控等内容。 d. 数据设备类要求(f)是等保2.0标准中专门对数据安全进行要求的一项内容,它主要包括数据备份、数据恢复、数据存储、数据传输等方面的安全要求。 综上所述,a、b、c、d选项所描述的等保2.0标准中对技术安全要求的分工是正确的。 ### 回答2: 等保2.0标准中对技术安全要求主要包含了信息安全类要求、服务保证类要求、其他安全保护类要求和数据设备类要求。 a. 信息安全类要求指的是对信息系统的各种组成部分、信息传输和处理过程以及相关的信息安全协议、算法等进行安全要求和控制。这是等保2.0标准中非常重要的一部分。 b. 服务保证类要求主要涉及系统的可用性、可靠性、灾备能力、响应能力等方面的要求。这些要求旨在确保信息系统随时可用,并且能够及时处理异常情况。 c. 其他安全保护类要求主要包括物理环境安全、人员安全、网络安全、应用软件安全等方面的要求。这些要求涉及到信息系统运行环境的各个方面和安全管理控制的要求。 d. 数据设备类要求主要涉及到数据的存储、传输、备份、还原等方面的要求。这些要求着重保护重要数据的安全性和完整性。 所以以上说法都正确,它们都是等保2.0标准中对技术安全方面的要求的不同分类。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值