楼主: yulihua49

[讨论] 侃一下关于程序的“柔性”

[复制链接]
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
241#
 楼主| 发表于 2025-10-8 17:03 | 只看该作者
guostong 发表于 2011-8-23 22:13
见过你写的关于exclude some columns 的解决方案,我实在想不出现在这种方案能够适用的场景,不会是拨号上 ...

看一下240楼,是不好懂还是效率低?

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
242#
发表于 2025-10-13 05:40 | 只看该作者
余老师,曾经参与这个帖子的那些人,大部分都不会再来论坛了,你现在是对着空气战风车,或曰坟头蹦迪。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
243#
 楼主| 发表于 2025-10-15 16:37 | 只看该作者
本帖最后由 yulihua49 于 2025-10-16 18:10 编辑
newkid 发表于 2025-10-13 05:40
余老师,曾经参与这个帖子的那些人,大部分都不会再来论坛了,你现在是对着空气战风车,或曰坟头蹦迪。

哦哈哈,对空气弹琴,自娱自乐,其实不针对他,针对的是他提出的问题。
最近跟老同事聊了一下,那个不当需求的cms项目还在运行,离开十几年了,系统是非常稳定,没有任何问题,没有替代方案。它之后的ACC项目快下马了,由新的afc2.0取代,新程序是JAVA写的,闸机检票数据直接入数据库。柔性编程还一个用处,一个程序可以处理多个表。下面这段程序是数据去重,为6个表进行操作,到底处理的是哪个表,由txn_dau确定,挺复杂的,发一部分。如果为每一个表写这么个程序,也够屎山。
方法是,先进行批量查询。ORACLE的批量select有个问题,就是不支持批量提供主键,查询一批主键是否存在。所以采用批量update+returnning “ROWID”的方法判断数据数组里每条记录是否在数据库中存在。
执行后,没有ROWID的数据将会被批量插入数据库。

int emass_cch_verification::batchRepeatVerfi(DAU *txn_dau,char *records_malloc,int recordsize,char *stmt,int repeatRecord[],int &realSzie)
{
        EMASS_DEBUG2("start batchRepeatVerfi");
        /*
        if(txn_dau==NULL)
        {
                EMASS_ERR("txn_dau is null");
                return -1;
        }
        */
        int ret;
        OAD oad;//Oracle Array Describe
        char *p;
        char col_name[83],*p1;
        //INT64 now;
        //按主键判断判重表的记录
        T_PkgType *tp=pkg_getType("ROWID",txn_dau->srm.tp);//取模板项
        if( !tp )
        {
                EMASS_ERR("表 %s 的模板缺少 ROWID 列!",txn_dau->srm.tabname);
                return -1;
        }
        if(recordsize==1)
        {        
                //单条记录优化处理
                ret=singleInsert(txn_dau,records_malloc,0,recordsize,stmt,repeatRecord,realSzie);
                return ret<0?ret:recordsize-ret;
        }
        //now=now_usec();
        
        OAD_init(&oad,txn_dau,records_malloc,recordsize);                        //OAD初始化

        //做假update,通过update可以批量条件处理来查重
        p=DAU_mk_update(txn_dau,stmt);
    p1=(char *)txn_dau->srm.tp[0].name;
    strtcpy(col_name,&p1,' ');
    p+=sprintf(p,"SET %s=%s ",col_name,col_name);                                //假修改
    p=mk_where(txn_dau->srm.pks,p);                                                                //按主键设置where条件
        DAU_mk_returning(txn_dau,(char *)"ROWID",p);                                                // 返回ROWID,重复记录时ROWID不为空

        ret=OAD_mk_update(&oad,stmt);                                                                //生成语句,prepare,准备绑定区
        if (ret==0)
        {
                ret=OAD_exec(&oad,0,recordsize);                                                        //执行批量
生成的语句这个样:
OAD.cpp(540) OAD_mk_update: "OAD_mk_update:sth=0,stmt=UPDATE EMASS_TRANS.T_TXN_REPEAT_DDT SET settlement_date=settlement_date WHERE card_serial_number=:1 AND txn_date_time=TO_DATE(:2,'YYYY-MM-DD HH24:MI:SS') AND device_id=:3 AND udsn=:4 AND line_number=:5 AND ud_subtype=:6 AND ud_type=:7 RETURNING ROWID INTO :8,"

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
244#
 楼主| 发表于 2025-10-15 21:11 | 只看该作者
newkid 发表于 2025-10-13 05:40
余老师,曾经参与这个帖子的那些人,大部分都不会再来论坛了,你现在是对着空气战风车,或曰坟头蹦迪。

这个版也是好凉快呀,经济形势不好,企业生存艰难,谁还有钱开发软件呀,有几个大平台能做网购就行了,这种大数据量的数据库编程,越来越没需求了。今后看AI的吧。

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
245#
发表于 2025-10-15 22:33 | 只看该作者
多个主键的SELECT可以用INLIST:
select id from my_table where id in (id1,id2,id3,...)
最多支持1000个,你当然可以用嵌套表/可变数组类型加上table()操作符,这样是把整个数组作为一个变量绑定。
你这个所谓的“去重”就暴露出不写SQL的人的思路缺陷了。你查到主键下一步准备干嘛?无非就是把不存在的数据添加进去。这完全可以用INSERT...SELECT...WHERE NOT EXISTS...或者MERGE来实现,支持数组绑定,像你这样拆成两个动作完全是多此一举。那个UPDATE更是搞笑,UPDATE是一种昂贵的操作,会生成redo,如果表上面有物化视图,会触发很多不必要的刷新操作。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
246#
 楼主| 发表于 2025-10-16 18:07 | 只看该作者
本帖最后由 yulihua49 于 2025-10-16 20:51 编辑
yulihua49 发表于 2025-10-15 21:11
这个版也是好凉快呀,经济形势不好,企业生存艰难,谁还有钱开发软件呀,有几个大平台能做网购就行了,这种 ...

INSERT...SELECT...WHERE NOT EXISTS returning ROWID  into  :ROWID 应该可以,当时不知道有这个,早点跟你聊聊就好了。
不写SQL也可以生成这个语句。凡是你写出来的语句我都能生成,只不过我不会。如果你写的语句我生成不了,我就会改进它。
243楼我把语句贴出来了,假修改也会有这些毛病吗?
这个肯定可以效率更高,我那个已经达到每秒处理35000记录了,要求是不低于每秒5000。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
247#
 楼主| 发表于 2025-10-16 18:26 | 只看该作者
本帖最后由 yulihua49 于 2025-10-16 18:30 编辑
newkid 发表于 2025-10-15 22:33
多个主键的SELECT可以用INLIST:select id from my_table where id in (id1,id2,id3,...)最多支持1000个,你 ...
这是后续的插入语句,我估计你没耐心看,我也是。写这一堆东西,更烦,还容易错。
  1. bind_ins:prepare sth=0,stmt=INSERT INTO EMASS_TRANS.T_YKTOR_CREDIT_PAY_MATCH (streamin
  2. g_session_id,record_index,pack_uid,host_name,txn_ssn_a,txn_ssn_b,data_version,settlement_date,business_date,ud_type,ud_su
  3. btype,card_issuer_id,destination_participant_id,product_issuer_id,card_type,source_participant_id,service_participant_id,
  4. entry_source_participant_id,trip_origin_location,entry_device_id,entry_udsn,entry_time,entry_sam_id,entry_ctsn,entry_mode
  5. ,current_location,device_id,udsn,txn_date_time,sam_id,ptsn,exit_mode,reconciliation_date,product_type,card_serial_number,
  6. should_pay_value,value_per_ride,pass_end_date_time,overtime_ajust_value,transaction_value,discount_lowpeak,discount_cardt
  7. ype,discount_value_sum,trans_value_before,trans_value_after,integral_startdate,match_type,charge_type,currency_indicator_
  8. fin_details,issuer_abort_reason,iss_exception_proc_abrtd,iss_exception,iss_txn_reflection,issr_verific_result,issr_card_v
  9. erific_result,issr_app_verific_result,issr_product_verific_result,cch_verific_result_field,cch_flags_txn_portion,cch_flag
  10. s_txn_summarised,cch_flags_txn_forwarded,cch_flags_txn_apportioned,cch_txn_good_for_summaries,cch_no_further_proc,cch_exc
  11. eption,cch_txn_not_to_issuer,cch_txn_approved,cch_verification_start_time,cch_verification_end_time,exception_list,produc
  12. t_subtype) VALUES ( :1, :2, :3, :4, :5, :6, :7,TO_DATE(:8,'YYYY-MM-DD HH24:MI:SS'),TO_DATE(:9,'YYYY-MM-DD HH24:MI:SS'), :
  13. 10, :11, :12, :13, :14, :15, :16, :17, :18, :19, :20, :21,TO_DATE(:22,'YYYY-MM-DD HH24:MI:SS'), :23, :24, :25, :26, :27,
  14. :28,TO_DATE(:29,'YYYY-MM-DD HH24:MI:SS'), :30, :31, :32,TO_DATE(:33,'YYYY-MM-DD HH24:MI:SS'), :34, :35, :36, :37,TO_DATE(
  15. :38,'YYYY-MM-DD HH24:MI:SS'), :39, :40, :41, :42, :43, :44, :45, :46, :47, :48, :49, :50, :51, :52, :53, :54, :55, :56, :
  16. 57, :58, :59, :60, :61, :62, :63, :64, :65, :66, :67,TO_DATE(:68,'YYYY-MM-DD HH24:MI:SS'),TO_DATE(:69,'YYYY-MM-DD HH24:MI
  17. :SS'), :70, :71)

复制代码


使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
248#
 楼主| 发表于 2025-10-16 18:41 | 只看该作者
本帖最后由 yulihua49 于 2025-10-16 20:49 编辑
yulihua49 发表于 2025-10-16 18:26
这是后续的插入语句,我估计你没耐心看,我也是。写这一堆东西,更烦,还容易错。

这是同一个程序生成的另一张表,列数不同哦,表示,一个程序可以处理不同的表,其中各个日期时间列,可以有不同格式,他们不会玩列属性修改(有这个功能):

  1. bind_ins:prepare sth=0,stmt=INSERT INTO EMASS_TRANS.CUT_AUDIT (streaming_session_id,da
  2. ta_version,txn_class,txn_revision,txn_ssn_a,txn_ssn_b,ols_txn_type,settlement_date,application_validation_flags,host_name
  3. ,multipart_txn_count,issuer_abort_reason,acquirer_id,destination_participant_id,account_type,portioned_txn_flag,format_ve
  4. rsion,txn_date_time,source_participant_id,device_id,sam_id,udsn,service_participant_id,device_location,device_ssn,busines
  5. s_date,transaction_status,cd_set_version,reconciliation_date,ud_type,ud_subtype,ykt_ud_type,ykt_ud_subtype,device_home_de
  6. pot,mass_installation_id,iss_exception_proc_abrtd,iss_exception,iss_txn_reflection,cch_flags_txn_portion,cch_flags_txn_su
  7. mmarised,cch_flags_txn_forwarded,cch_flags_txn_apportioned,cch_txn_good_for_summaries,cch_no_further_proc,cch_exception,c
  8. ch_txn_not_to_issuer,cch_txn_approved,cch_verification_start_time,cch_verification_end_time,exception_list,key_version,tr
  9. ansaction_value,currency_indicator_fin_details,sales_tax,discount,tax_rate,tax_code,number_of_payments,payment_method,pay
  10. ment_value,partial_transaction_value,partial_sales_tax,invoice_not_printed,number_of_key_value_pairs,snapshot_reason_code
  11. ,audit_register_values,audit_register_ids,adjustment_settlement_date,adjust_id,adjustment_approved,reason,account_id,numb
  12. er_auth,post_settlement_date,original_settlement_date,settlement_approved,claim_date,claim_id,claim_amount,claim_approved
  13. ,claim_ref_number,record_index,pack_uid,cch_verific_result_field,short_card_serial_number) VALUES ( :1, :2, :3, :4, :5, :
  14. 6, :7,TO_DATE(:8,'YYYY-MM-DD HH24:MI:SS'), :9, :10, :11, :12, :13, :14, :15, :16, :17,TO_DATE(:18,'YYYY-MM-DD HH24:MI:SS'
  15. ), :19, :20, :21, :22, :23, :24, :25,TO_DATE(:26,'YYYY-MM-DD HH24:MI:SS'), :27, :28,TO_DATE(:29,'YYYY-MM-DD HH24:MI:SS'),
  16. :30, :31, :32, :33, :34, :35, :36, :37, :38, :39, :40, :41, :42, :43, :44, :45, :46, :47,TO_DATE(:48,'YYYY-MM-DD HH24:MI
  17. :SS'),TO_DATE(:49,'YYYY-MM-DD HH24:MI:SS'), :50, :51, :52, :53, :54, :55, :56, :57, :58, :59, :60, :61, :62, :63, :64, :6
  18. 5, :66, :67,TO_DATE(:68,'YYYY-MM-DD HH24:MI:SS'), :69, :70, :71, :72, :73,TO_DATE(:74,'YYYY-MM-DD HH24:MI:SS'),TO_DATE(:7
  19. 5,'YYYY-MM-DD HH24:MI:SS'), :76,TO_DATE(:77,'YYYY-MM-DD HH24:MI:SS'), :78, :79, :80, :81, :82, :83, :84, :85)
复制代码

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
249#
发表于 2025-10-16 21:46 | 只看该作者
yulihua49 发表于 2025-10-16 18:07
INSERT...SELECT...WHERE NOT EXISTS returning ROWID  into  :ROWID 应该可以,当时不知道有这个,早点跟 ...

insert ... select 是不支持returning子句的。merge直到23ai才支持returning。如果是pl/sql它会返回一个数组SQL%BULK_ROWCOUNT供你查看分别插入多少行。如果改用 insert /*+  ignore_row_on_dupkey_index */ values ... 就可以用returning。但是你要这些returning返回值干什么呢?这还是一个思路的问题。
243就是一个常规的update,数据库可不管你真假update,那些开销全部逃不了。
你生成的那些“灵活”的插入语句,在PL/SQL中当然可以用数据字典来生成,而且说到底它的逻辑十分简单,就是在做**档的工作。SQL的真正威力不在于此,它的写入可以带很复杂的计算功能,全部在一个语句搞定。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
250#
 楼主| 发表于 2025-10-17 20:26 | 只看该作者
newkid 发表于 2025-10-15 22:33
多个主键的SELECT可以用INLIST:select id from my_table where id in (id1,id2,id3,...)最多支持1000个,你 ...

你这个办法跟那哥们说了,他非常感兴趣。
要测试一下。如果成功,有望性能提高到50000每秒。
另外,有没有办法实现:
数据库里没有就插入,有了就update,用新数据替换老数据?

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表