CURSOR C1 IS
          SELECT 'ANALYZE TABLE ' ||u.table_name||' COMPUTE STATISTICS ' FROM User_Tables u WHERE u.table_name IN (……);  BEGIN
      OPEN c1;
      FETCH c1 INTO v_sql;
      WHILE c1%FOUND 
      LOOP
          EXECUTE IMMEDIATE v_sql;
          FETCH c1 INTO v_sql;
      END LOOP;
      CLOSE c1;
----------------------------------------
如果我把定义游标的那一句单独拿出来执行,即:select analyze table u.table_name compute statistics from user_tables u where u.table_name= 'TABLENAME';
则会报错,它怎么可以在pl/sql中执行呢?貌似这样的写法也是不对的吧?

解决方案 »

  1.   

    你拿出来的引号呢? 被你“吃”了么?
    这个过程的目的是,拼接 sql,然后动态执行 EXECUTE IMMEDIATE v_sql;
    仔细想想。
      

  2.   


    ANALYZE TABLE table_name COMPUTE STATISTICS;
    --这句话是手动分析表,获得分析信息,但是数据库中有很多个表,如果手动写就得为每个表都写一个sql,
    --而每个sql只有表名不同,因此为了一次性获得语句,可以利用user_tables 这个视图中的 table_name字段
    --把sql都拼出来,这就是游标的作用--然后在下面动态执行拼出来的sql。
    --你拿出来的sql 不对
    select 'analyze table '|| u.table_name ||' compute statistics' from user_tables u where u.table_name= 'TABLENAME'
      

  3.   

    把IS后面的select语句整个拿出来(包括引号),那该语句是可执行的。
    游标的作用是为了访问查询结果集中的多条记录。
      

  4.   


    我知道游标里是动态拼出来的,比如有很多表名前缀一样,也可以在过程里用动态拼接的方法实现查询:select * from 'HQY_'||v_name; (v_name=month1 ... month12)
    那么我就可以把这句单独拿出来执行:select * from HQY_month4;
    为什么我这里想把它还原后单独拿出来执行就不行了呢?!
      

  5.   

    SQL语句是pl/sql语句是有区别的,
    你的游标的意思就是,根据你的where 条件,就是in哪些表,查询数据字典,生成动态的用来执行分析表的sql语句,在下面的pl/sql块中,打开游标,循环取出语句执行,对表进行分析,execute immediate 是pl/sql 语句 执行动态sql,fetch 提取游标中得sql语句放入到v_sql变量中
      

  6.   


    也就是说有些pl/sql块中的动态语句是可以自己先“拼装”出来执行看下,有些则不行?
      

  7.   

    execute immediate 后面是动态sql 可以是拼装的,包括ddl,dml语句
      

  8.   


    没有不行的,是你不会拼。SELECT 'ANALYZE TABLE ' ||u.table_name||' COMPUTE STATISTICS ' FROM User_Tables u WHERE u.table_name IN (... ...)本身就是个语句,怎么不能执行?这个游标输出的动态语句 是一系列的 
    ANALYZE TABLE  tb1 COMPUTE STATISTICS
    ANALYZE TABLE  tb2 COMPUTE STATISTICS 
    ANALYZE TABLE  tb3 COMPUTE STATISTICS
    ................................ 
    ANALYZE TABLE  tb4 COMPUTE STATISTICS哪个执行有问题? 
      

  9.   

    因为过程里的动态语句:select * from 'HQY_'||v_name; (v_name=month1 ... month12)
    那么我就可以把这句单独拿出来执行:select * from HQY_month4;向上面这个我就能拼出来了,但是现在这个游标里的如果我拼出来的话就是:select analyze table u.table_name compute statistics from user_tables u where u.table_name= 'TABLENAME'; 这样的话肯定有问题
    至于你说得到的是ANALYZE TABLE tb1 COMPUTE STATISTICS,这就是我不明白的地方啊!为什么前面的select 这些没有了?
      

  10.   

    引用 9 楼 forgetsam 的回复:
    一 人家的游标是
    SELECT 'ANALYZE TABLE ' ||u.table_name||' COMPUTE STATISTICS ' FROM User_Tables u 
    已经拼好了,不用你拼。你想看就直接执行你拼出来的select analyze table u.table_name compute statistics from user_tables u 完全就没理解哪个是常量哪个是结构第一个问题解决了吧?
    二 执行select 'ABC' from dual 
    出来的结果是 'ABC' 还是 select 'ABC' from dual ,这个你知道吧,第二个问题也解决了吧?完毕。
      

  11.   

    to forgetsam:
    还是有点不明白。
    看你的意思是说游标里已经拼好了,用到它时就直接是ANALYZE TABLE tb1 COMPUTE STATISTICS
    就像最普通的:
    cursor cur_stu is 
    select stuno,stuname from student order by stuno;
    当用到cur_stu时实际就只剩下学号跟姓名了。
    但我不明白的是像游标定义里的一般也都是可以直接先拿出来执行的啊,就像可以把
    select stuno,stuname from student order by stuno这句拿出来一样。还有select 'ABC' from dual  这个很好理解,但是现在这个游标里定义的并不是from dual表啊,如果它是select 'ANALYZE TABLE tb1 COMPUTE STATISTICS' from dual,那就不能实现分析多个表了
      

  12.   

    to forgetsam:
    还是有点不明白。
    看你的意思是说游标里已经拼好了,用到它时就直接是ANALYZE TABLE tb1 COMPUTE STATISTICS
    就像最普通的:
    cursor cur_stu is  
    select stuno,stuname from student order by stuno;
    当用到cur_stu时实际就只剩下学号跟姓名了。
    但我不明白的是像游标定义里的一般也都是可以直接先拿出来执行的啊,就像可以把
    select stuno,stuname from student order by stuno这句拿出来一样。
    ---对,你说了,直接,所以,你别给人家解析还有select 'ABC' from dual 这个很好理解,但是现在这个游标里定义的并不是from dual表啊,如果它是select 'ANALYZE TABLE tb1 COMPUTE STATISTICS' from dual,那就不能实现分析多个表了---别想偏了,什么叫多?你现在还没看懂一,select 'ANALYZE TABLE tb1 COMPUTE STATISTICS' from dual 那就不能实现分析多个表了--很好,你现在接近了
    select 'ANALYZE TABLE tb1 COMPUTE STATISTICS' from user_tables 是不是能分析多次表了?select 'ANALYZE TABLE '||table_name||' COMPUTE STATISTICS' from user_tables
    知道什么意思了吧
      

  13.   

    貌似明白了,还要再消化消化,感谢forgetsam!!