表是用户在使用应用中动态创建或修改的。想使用触发器或存储过程(或其他任何方式)实现数据校验,要求校验如下些类型:空/非空;数据类型(数字/字符)、日期格式(固定的几种,如YYYYMMDD等)、数据范围(参考另一张表的字段)。如果表、字段是定下来的,trigger就好写了。但关键是表是用户动态创建的。当然,有另外的表保存了整个用户创建表的信息,包括包含哪些字段,字段类型,格式,参考哪张表的哪个字段等初步想法:创建一个校验模版sql(create trigger or procedure),然后在创建表的同时,将模版中的与表、字段相关的内容替换,再执行替换后的模版sql,动态生成trigger or procedure. 但实现起来有问题,关键是 :NEW.* 的个数不定。哪位兄弟有高招?分不是问题。

解决方案 »

  1.   

    :NEW.* 的个数不定。
    我不理解既然是动态创建
    那么字段的个数变化,语句也跟着变化就行了
      

  2.   

    :NEW.* 的个数不定。
    我不理解既然是动态创建
    那么字段的个数变化,语句也跟着变化就行了
      

  3.   

    为什么不利用Oracle Constraint来进行数据的校验?
    就你这里所说的你把日期存储成字符串,这样无法通过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来传递,然后你在该过程中通过你存储的表、字段类型、格式、参考那张表等信息很容易动态验证的。
      

  4.   

    to  bzszp(SongZip)
    thanks,你的思路给我提了个醒,需要校验的字段个数不定,先用循环动态生成这块不定的地方,再放进去。to nyfor(nyfor)
    你的思路也很好,但不知道vc里面调用时能否将tab_str传进去?使用ado/oledbps. 不用constraint是因为:
    一、想获得出错的详细信息,如:是哪个数据不能为空,哪个字段的数据范围有错
    二、参考其他表时,有加入where条件的情况,用constraint无法实现。thank you 2 very much.
      

  5.   

    VC 中应该不可以使用Oracle自定义的对象类型。
    如果你的参数组合起来长度不算太大(我不清楚varchar2参数的最大允许长度)的话,你也可以把这些个参数组成一个字符串来代替 pl/sql table 作为参数来传递,再在过程中拆解。
      

  6.   

    动态创建表,动态创建校验模版就是了:
    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;
    /