非常感谢,学到不少。
tabname = strtok_r(cols, ":", &savep);就是利用原地址构
cols_list,构建完原地址就没用了。
try {
dao = new SdbcDAO(db_conn, tabname);
} catch(...) {
ShowLog(...);
return -2;
}
若 dao->Data_init() 或 BB_Tree_Add 异常(这些函数未标明 noexcept),则 dao 可能未被 delete,且 cols_list 可能未释放。
那时候cols_list还未建立,无需释放。我担心的是,构造函数能try吗?另外tree_add是把node内容复制到分配的空间。与它原来的存储没有关系。这也有点问题,如果node里边有指向自己的指针,复制后就不对了。这个树的设计是自己的需求,考虑到局部变量的节点。
auto* tp = dao->getTemplate(cn.c_str());
这个tp是要放到cols_list里边的,代表一个列的参数。
如果空,说明文件指明的列名,数据库里不存在,就是null。但是它是个有效节点。每当遇到这列数据,看到数据库里没有,就跳过这个数据,后边的列不会错位。它成为占位列。再说一遍,tp=null时,仅仅写了一个日志,该节点是加入到cols_list里边的,是个正常节点。好像前边哪楼我说过,需求里要求文件中出现数据库中不存在的列名,则跳过该数据,后边的列数据不得错位,这就是具体做法。
关于sql注入,在record里,全是数据,并不用于生成语句,仅仅是被被绑定的变量,就算写一个sql语句,也只会被存到数据库里。这不怨它,它很聪明,我还没讲到怎么绑定变量呢。看看158楼那个自动生成的语句,外部给的任何东西都被:绑进数据库,不会得到执行。
在这个实例里,insert是没有参数,所以有*stmt=0,需要一个空间来生成sql语句。
但是可能会有参数,如insert into table(…)values(…) returning ROWID INTO :ROWID;
或 insert into table(…) select…
我的设计留了这个口子。
表名变大写的问题,Oracle大小写不敏感,为了可读变大写的,其他数据库可能不合适。
评分,可读性安全性拒绝。健壮性承认,错误处理已经有想法。缓冲器尺寸可以通过各种方法设置,底层是否改string的问题在犹豫。
性能因为实际是c程序,没有用STL,用平衡二叉树是合适的动态有序数据存储,构建一次使用多次,不是高频次的增删,BB树和RB树没有多大区别。遍历一个树和遍历一个list也没多大性能差别。
安全性补充,本反序列化考虑到外部数据长于成员空间的问题,超长的内容会被截断,绝无溢出风险。
说我函数长?再短逻辑就不完整了。看看158楼的语句,
反序列化69个列,不要69行?绑定69列不要69行?要是150列的表呢?
我知道有些框架一个函数四五行,不知道要深入多少层都找不到是干啥呢。
只好前半截搞个函数后半截搞个函数,更不好懂了吧!
我还挺得意这么短的程序办了这么个事。
看看171楼的批量处理,就那么几行,如果不是柔性程序,几十个列的绑定就得几十行,有6个表你给我写6遍,8个表写8遍。就一个算法。
我这个才真正实现了算法与数据独立。
【 在 yuanmo 的大作中提到: 】
: 这个Claude Code前几天就猜测是这个原因。原文我没贴过来。
: DeepSeek的结论类似:
:
: ...................
--。
※ 修改:·ylh1969 于 Jun 4 22:44:08 2026 修改本文·[FROM: 221.221.54.*]
※ 来源:·水木社区
http://www.mysmth.net·[FROM: 221.221.54.*]
修改:ylh1969 FROM 221.221.54.*
FROM 221.221.54.*