|
原帖由 newkid 于 2010-2-23 23:47 发表 ![]()
如果仅仅是数据加载,不涉及任何事务处理逻辑,映射到结构就没什么意义,一个二维数组就够了。你需要的只是一个缓存,从文件读入,再送给目标数据库。
通用的数据抽取转换工具已经很多了,我只要使用就行。
你的意思是手工处理游标更快?等我有空比较一下。
hibernate我们是不用的,看不到任何好处。我们大量使用存储过程。
看模板时,知道此表如此。----- 如果有聚合,或者多表连接,你就不能用表模板了,你看到的已经不是表结构了
看程序时,如此访问此表。逻辑很清晰。------- 同上,如果是复杂SQL,你还得回头再去看模板才有意义。
可见用了你的DAU,你就会培养出一堆只知道单表操作的程序员。
那个席位发布程序报什么错?让它出错的运行步骤是什么?我自己的测试结果(连续运行两次程序),第二次什么数据也不产生而且不报错。
绑定变量需要空间,DAU_init分析了表结构后形成模板,然后按模板形成buffer,这个buffer就是一个结构布局。
然后,DAU_dispack就把字符串数据拆包到这个buffer,DAU_insert就把这个buffer绑定。这处处都要用模板,否则你怎么知道都有多少列,各是什么类型,多长,什么格式?你自己分析,然后分配空间,然后绑定变量?这不正是DAU帮你做的吗?
make_seats(null,0,0,1);
ERROR at line 1:
ORA-00001: unique constraint (TICKET.SYS_C0017007) violated
ORA-06512: at "TICKET.MAKE_SEATS", line 23
ORA-06512: at line 11
“
看模板时,知道此表如此。----- 如果有聚合,或者多表连接,你就不能用表模板了,你看到的已经不是表结构了
看程序时,如此访问此表。逻辑很清晰。------- 同上,如果是复杂SQL,你还得回头再去看模板才有意义。
可见用了你的DAU,你就会培养出一堆只知道单表操作的程序员。”
我就知道你会这么说,我一再一再说,DAU支持多表集合操作,一个结构对应的“表”是广义的,前边说了,有“表 表达式”你理解是什么含义吗?
看一下DAU内部分析表结构的模板:
static T_PkgType PATTERN_type[]={
{CH_CHAR,49,"c.table_name table_name",0,-1},
{CH_CHAR,83,"c.column_name column_name"},
{CH_SHORT,sizeof(short),
"decode(data_type, 'CHAR',1, 'VARCHAR',1, 'VARCHAR2',1, 'DATE',129,'TIMESTAMP(6)',129,"
"'FLOAT',8,'LONG',126, 'RAW',0, 'BINARY_DOUBLE',8,'BINARY_FLOAT',7,"
" 'NUMBER',decode(nvl(DATA_SCALE,0),0, "
"decode(nvl(data_precision,0), 0,257, 1,2, 2,2, 3,3, 4,3, 5,4, 6,4, 7,4, 8,4,"
"9,4, 10,6, 11,6, 12,6, 13,6, 14,6, 15,6, 16,6, 17,6, 18,6, 257),8),257) "
"Fld_Column_Type"},
{CH_SHORT,sizeof(short),"decode(data_type, 'CHAR',data_length+1, 'VARCHAR',data_length+1,"
"'VARCHAR2',data_length+1, 'DATE',20,'TIMESTAMP(6)',27,'FLOAT',8,'BINARY_DOUBLE',8,'BINARY_FLOAT',4, "
"'LONG',-1, 'NUMBER', "
"decode(nvl(DATA_SCALE,0),0,decode(nvl(data_precision,0), 0,35, 1,1, 2,1, 3,2, "
"4,2, 5,4, 6,4, 7,4, 8,4, 9,4, 10,8, 11,8, 12,8, 13,8, 14,8, 15,8, 16,8, 17,8, "
"18,8, data_precision+2),8),data_length) "
"Fld_Column_Len"},
{CH_CHAR,30,"decode(data_type, 'CHAR',null, 'VARCHAR',null, 'VARCHAR2',null, "
"'DATE','YYYY-MM-DD HH24:MI:SS','TIMESTAMP(6)','YYYY-MM-DD HH24:MI:SS.FF6','FLOAT','%lg','LONG',null, "
"'BINARY_DOUBLE','%lg', 'BINARY_FLOAT','%g', 'NUMBER',decode(nvl(DATA_SCALE,0),0,null,"
"'%'||TO_CHAR(data_precision+2)||'.'||TO_CHAR(DATA_SCALE)||'lf'),null) "
"Fld_Format"},
{CH_SHORT,sizeof(short),"k.position"},
{-1,0,0,0}
};
就是一个多表的列表达式。
- //PATTERN_s *pp是与上述模板对应的数据结构。
- typedef struct {
- char Fld_Tlb_Name[49];
- char Fld_Column_Name[83];
- short Fld_Column_Type;
- short Fld_Column_Len;
- char Fld_Format[30];
- short Fld_PK;
- } PATTERN_s;
- static int descDAO(DAU *DP,T_SQL_Connect *SQL_Connect,PATTERN_s *pp,char *stmt)
- {
- int ret;
- char pattTable[256];
- // 如果是其它数据库,要改。
- //生成表名表达式。
- strcpy(pattTable, "all_tab_columns c, "
- "(select table_name,column_name,position "
- "from all_cons_columns "
- "where owner= :column_name and table_name=:table_name and position is not null) k ");
- DAU_init(DP,SQL_Connect,pattTable, pp,PATTERN_type);
- //条件表达式
- strcpy(stmt,"where c.table_name = k.table_name(+) "
- "and c.column_name = k.column_name(+) "
- "and c.owner = :column_name and c.table_name=:table_name "
- "order by c.table_name, c.column_id ");
- ret=DAU_select(DP,stmt,0);
- if(ret<=0) ShowLog(1,"descDAO:DAU_select stmt=%s",stmt);
- return ret;
- }
复制代码
生成的语句和分析的结果:
5 loadsth:28746 02/23 09:38'00 ,bind_select:cursor=0,sqlo_prepare=SELECT c.table_name table_name,c.column_name column_name,decode(data_type, 'CHAR',1, 'VARCHAR',1, 'VARCHAR2',1, 'DATE',129,'TIMESTAMP(6)',129,'FLOAT',8,'LONG',126, 'RAW',0, 'BINARY_DOUBLE',8,'BINARY_FLOAT',7, 'NUMBER',decode(nvl(DATA_SCALE,0),0, decode(nvl(data_precision,0), 0,257, 1,2, 2,2, 3,3, 4,3, 5,4, 6,4, 7,4, 8,4,9,4, 10,6, 11,6, 12,6, 13,6, 14,6, 15,6, 16,6, 17,6, 18,6, 257),8),257) Fld_Column_Type,decode(data_type, 'CHAR',data_length+1, 'VARCHAR',data_length+1,'VARCHAR2',data_length+1, 'DATE',20,'TIMESTAMP(6)',27,'FLOAT',8,'BINARY_DOUBLE',8,'BINARY_FLOAT',4, 'LONG',-1, 'NUMBER', decode(nvl(DATA_SCALE,0),0,decode(nvl(data_precision,0), 0,35, 1,1, 2,1, 3,2, 4,2, 5,4, 6,4, 7,4, 8,4, 9,4, 10,8, 11,8, 12,8, 13,8, 14,8, 15,8, 16,8, 17,8, 18,8, data_precision+2),8),data_length) Fld_Column_Len,decode(data_type, 'CHAR',null, 'VARCHAR',null, 'VARCHAR2',null, 'DATE','YYYY-MM-DD HH24:MI:SS','TIMESTAMP(6)','YYYY-MM-DD HH24:MI:SS.FF6','FLOAT','%lg','LONG',null, 'BINARY_DOUBLE','%lg', 'BINARY_FLOAT','%g', 'NUMBER',decode(nvl(DATA_SCALE,0),0,null,'%'||TO_CHAR(data_precision+2)||'.'||TO_CHAR(DATA_SCALE)||'lf'),null) Fld_Format,k.position FROM all_tab_columns c, (select table_name,column_name,position from all_cons_columns where owner= :1 and table_name=:2 and position is not null) k where c.table_name = k.table_name(+) and c.column_name = k.column_name(+) and c.owner = :3 and c.table_name=:4 order by c.table_name, c.column_id
5 loadsth:28746 02/23 09:38'00 mkpk:tjdate|unit|tabname|flg|
耐心仔细看,不是DAU难懂,真正是SQL难懂。
这就是我们先前pk的tjrb表。
我给你导读一下:
分析表结构需要6个值,在模板中6个大括号,前两个比较简单(表名,列名),第3,4,5是复杂表达式,它们分别是类型、长度、格式,将ORACLE的表示法转换为SDBC的表示法。最后一个是主键,另一个表读出来的。
表表达式就是FROM后边的一堆东西。
如此复杂的语句都可以处理,那些count、sum、total,avg...更不在话下。
大家看看,一个支离破碎的SQL好懂呢还是完整语句好懂,看看日志里的那个东西吧(你如果喜欢自己写语句,就是这个东西)。简直是个怪物,不把它五脏六腑掏出来是研究不透的。语句是别人写的,我学习分析,消化了,变成模板,后来在模板的基础上又进行了修改,有了模板修改很方便。比如增加了TIMESTAMP、RAW类型,在原语句上改实在是困难,太容易错了。在改的时候,思路很简单,新类型的类型码,长度,格式。逻辑是非常清晰的。语句分解后带来的好处太大了。
借一句广告语:用了才知道,这正是你需要的。
我可以告诉你SDBC不能做什么:
不能处理BLOB,前导with.....as...的语句,带returnning的语句。
如果需要,在DAU环境下可以调sqlora来处理,也可以调存储过程来处理。SDBC支持你使用存储过程,见我blog里SDBC说明书。
但有些事还要前端做,比如大系统后端是RAC,前端是与数据库分离的应用服务器,涉及局部资源,就无法用存储过程。
SDBC是3层C/S/S模型,所有数据必须序列化,因此有了SRM,有了在SRM基础上的DAU。你不能说什么有用武之地什么没有,它是一个完整系统不可割裂,它需要一个全新的视角(也是最古老的)去看待程序和数据。
[ 本帖最后由 yulihua49 于 2010-2-24 11:44 编辑 ] |
|