小弟oracle刚刚接触。有几个问题不很明白。
1.oracle自增,不用序列,那用max(id)+1吧。比如:select max(id)+1 into id from dual;请看下面的问题:
我有个用户表users 对应菜单表menus,是一对多关系。他们的关系表为:usermenus 我想用下面的语法:
    传入参数:userid_in number,
              menuids_in varchar2 --菜单id字符串,例如:‘1,3,5’insert into usermenus(id,userid,menuid) select(usermenus的自增id,userid_in,fn_split(menuids_in,','));红色部分要怎么表示呢?不知道我说明白没有。2.问题2:老板规定oracle必须全部用存储过程。以前用惯了sqlserver,后来发现oracle的select语句在存储过程里面要报错。查了下说要用游标才能返回数据。能给我一个最最简单的存储过程,里面包含游标的操作不?

解决方案 »

  1.   

    1.不知道为什么不用序列,那么写的性能要降低
    按你的意思,以这个例子
    create or replace procedure pro_test(userid_in in number,menuids_in in varchar2)
    is
    v_id number;
    begin
    select max(id)+1 into v_id from tt;
    insert into usermenus(id,userid,menuid) values (v_id,userid_in,fn_split(menuids_in,','));
    end pro_test;
    2.
    declare 
    cursor c1 is select * from tt;
    begin
    for cur1 in c1 loop
      dbms_output.put_line(cur1.id);
    end loop;
    end;
      

  2.   

    1,先赋值,select max(id)+1 into usermenus_id from dual; 然后就可以直接用了:insert into usermenus(id,userid,menuid) select(usermenus_id ,userid_in,fn_split(menuids_in,',')); 
      

  3.   

    2,最简单的例子,最最简单的存储过程,里面包含游标的操作:
    http://diegoball.javaeye.com/blog/462979
      

  4.   

    赞成使用max来实现自动增长,性能较好
      

  5.   

    在Oracle里建序列是最好的,如果用Max来获取序号的话,可能会因为并发而出错。。
      

  6.   

    2.游标返回数据问题
    用sys_refcursor
    create or replace procedure pro_test(c1 out sys_refcursor)
    as
    begin
    open c1 for select * from tt;
    end pro_test;
    --存储过程通过游标返回数据declare
    c1 sys_refcursor;
    tt_row tt%rowtype;
    begin
    pro_test(c1);loop
    fetch c1 into tt_row;
    exit when c1%notfound;
    dbms_output.put_line(tt_row.id);
    end loop;
    close c1;
    end;
    --调用过程导出数据
      

  7.   

    大哥,谢谢你们.可是就我说的第一个问题,你们忽略了个问题create or replace procedure pro_test(userid_in in number,menuids_in in varchar2)
    is
    v_id number;
    begin
    select max(id)+1 into v_id from tt;
    insert into usermenus(id,userid,menuid) values (v_id,userid_in,fn_split(menuids_in,','));
    end pro_test;这里的
    insert into usermenus(id,userid,menuid) values (v_id,userid_in,fn_split(menuids_in,','));
    insert into 语句是进行了批量插入,即每次的id都+1了的.
    而select max(id)+1 into v_id from tt;是只执行了一次.v_id的只是不变的,所以要报错违背唯一性约束的
      

  8.   

    批量插入...
    根据你的描述,这个过程是一条一条插入的啊
    每插入一条记录要运行一次过程,因此max(id)每次也会递增,不会违背约束才对
    不是很明白你说的是怎么回事,批量的话,给你个例子
    declare
    v_id number;
    begin
    select max(id) into v_id from tt;
    insert into usermenus(id,userid,menuid) 
      select v_id+rownum,userid_in,fn_split(menuids_in,',')) from dual
      connect by rownum<100;
    end;
    插入99条记录,id递增,不过不明白这样的话你要怎么处理userid和menuid
      

  9.   


    1.
    用max+1不好,
    1. 如果max可以用的话,只能保证表只能增加,不能删除,否则就要删除是去重新维护了
    2. 性能问题
    3. 并发出现的问题Oracle里通过sequenece来提高你需要的功能。
      

  10.   

    1.oracle自增,不用序列,那用max(id)+1吧。比如:select max(id)+1 into id from dual; 
    并发出现的问题应该注意