表是用户在使用应用中动态创建或修改的。想使用触发器或存储过程(或其他任何方式)实现数据校验,要求校验如下些类型:空/非空;数据类型(数字/字符)、日期格式(固定的几种,如YYYYMMDD等)、数据范围(参考另一张表的字段)。如果表、字段是定下来的,trigger就好写了。但关键是表是用户动态创建的。当然,有另外的表保存了整个用户创建表的信息,包括包含哪些字段,字段类型,格式,参考哪张表的哪个字段等初步想法:创建一个校验模版sql(create trigger or procedure),然后在创建表的同时,将模版中的与表、字段相关的内容替换,再执行替换后的模版sql,动态生成trigger or procedure. 但实现起来有问题,关键是 :NEW.* 的个数不定。哪位兄弟有高招?分不是问题。
我不理解既然是动态创建
那么字段的个数变化,语句也跟着变化就行了
我不理解既然是动态创建
那么字段的个数变化,语句也跟着变化就行了
就你这里所说的你把日期存储成字符串,这样无法通过Oracle Constraint来做校验外,别的都可以啊。另外你是不是可以写一个通用的存储过程而不是什么trigger来校验数据,比如
create type tab_str as table of varchar2(2000);
/
create function verify_data(p_tablename varchar2,p_values tab_str,p_columns tab_str) return boolean
.....
具体的过程体我就不描述了,我只想告诉你这个参数通过使用pl/sql table来传递,然后你在该过程中通过你存储的表、字段类型、格式、参考那张表等信息很容易动态验证的。
thanks,你的思路给我提了个醒,需要校验的字段个数不定,先用循环动态生成这块不定的地方,再放进去。to nyfor(nyfor)
你的思路也很好,但不知道vc里面调用时能否将tab_str传进去?使用ado/oledbps. 不用constraint是因为:
一、想获得出错的详细信息,如:是哪个数据不能为空,哪个字段的数据范围有错
二、参考其他表时,有加入where条件的情况,用constraint无法实现。thank you 2 very much.
如果你的参数组合起来长度不算太大(我不清楚varchar2参数的最大允许长度)的话,你也可以把这些个参数组成一个字符串来代替 pl/sql table 作为参数来传递,再在过程中拆解。
create procedure pro(p_id in varchar2,p_name in varchar2,p_table in varchar2)
as
str varchar(200);
begin
str:='create table '||p_table||' ('||p_id||' varchar2(10),'||p_name||' varchar2(20))';
execute immediate str;
commit;
str:='create trigger '||p_table||'_tri
before insert on '||p_table||'
for each row
begin
if :new.'||p_id||' >10 then
....
end if;
end';
execute immediate str;
end;
/