123
返回列表 发新帖
楼主: aniven

[PL/SQL] 存储过程中执行存储过程

[复制链接]
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
21#
发表于 2017-1-11 21:20 | 只看该作者
把owner修改了,重现了lz的问题
SQL> 11
11*        and owner in ('TEST');
SQL> c/TEST/HR
11*        and owner in ('HR');
SQL> /

过程已创建。

已用时间:  00: 00: 00.04
SQL> exec benben
BEGIN benben; END;

*
第 1 行出现错误:
ORA-00900: 无效 SQL 语句
ORA-06512: 在 "HR.BENBEN", line 18
ORA-06512: 在 line 1


已用时间:  00: 00: 00.12

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
22#
发表于 2017-1-11 21:27 | 只看该作者
在dbms_stat语句前加begin 后加end;
SQL> dbms_stats.gather_table_stats(ownname => 'HR',tabname => 'REGIONS',estimate_percent => 20,cascade => TRUE,force =>TRUE);
SP2-0734: 未知的命令开头 "dbms_stats..." - 忽略了剩余的行。
SQL> begin dbms_stats.gather_table_stats(ownname => 'HR',tabname => 'REGIONS',estimate_percent => 20,cascade => TRUE,force =>TRUE) e
nd;
  2  /
begin dbms_stats.gather_table_stats(ownname => 'HR',tabname => 'REGIONS',estimate_percent => 20,cascade => TRUE,force =>TRUE) end;
                                                                                                                              *
第 1 行出现错误:
ORA-06550: 第 1 行, 第 127 列:
PLS-00103: 出现符号 "END"在需要下列之一时:
:= . ( % ;
符号 ";" 被替换为 "END" 后继续。


已用时间:  00: 00: 00.07
SQL> begin dbms_stats.gather_table_stats(ownname => 'HR',tabname => 'REGIONS',estimate_percent => 20,cascade => TRUE,force =>TRUE);
end;
  2  /

PL/SQL 过程已成功完成。

已用时间:  00: 00: 00.62
SQL> create or replace procedure benben
  2  as
  3     vSqlStatement varchar2(10000);
  4
  5     cursor cur_gather_tab_statistics is
  6       select 'begin dbms_stats.gather_table_stats(ownname => ''' || owner ||
  7              ''',tabname => ''' || segment_name ||
  8              ''',estimate_percent => 20,cascade => TRUE,force => TRUE); end;'
  9         from dba_segments
10       where segment_type = 'TABLE'
11         and owner in ('HR');
12
13  begin
14
15    open cur_gather_tab_statistics;
16    fetch cur_gather_tab_statistics into vSqlStatement;
17    while cur_gather_tab_statistics%found loop
18    dbms_output.put_line(vSqlStatement);
19      execute immediate vSqlStatement;
20      fetch cur_gather_tab_statistics into vSqlStatement;
21    end loop;
22    close cur_gather_tab_statistics;
23
24  end;
25  /

过程已创建。

已用时间:  00: 00: 00.03
SQL> exec benben

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
23#
发表于 2017-1-11 22:59 | 只看该作者
这是动态PLSQL不是动态SQL, 所以要构造匿名块,即放在BEGIN END; 之间。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
24#
发表于 2017-1-12 00:53 | 只看该作者
〇〇 发表于 2017-1-11 21:27
在dbms_stat语句前加begin 后加end;
SQL> dbms_stats.gather_table_stats(ownname => 'HR',tabname => 'RE ...

你前面一段漏掉分号的代码没必要贴出来啊

使用道具 举报

回复
论坛徽章:
1
优秀写手
日期:2014-07-09 06:00:13
25#
 楼主| 发表于 2017-1-12 08:39 | 只看该作者
  1. SQL> declare
  2.   2    vsqlstatement varchar2(10000);
  3.   3    cursor cur_gather_tab_statistics is
  4.   4      select 'dbms_stats.gather_table_stats(ownname => ''' || owner ||
  5.   5             ''',tabname => ''' || segment_name ||
  6.   6             ''',estimate_percent => 20,cascade => TRUE,force => TRUE);'
  7.   7        from dba_segments
  8.   8       where segment_type = 'TABLE'
  9.   9         and segment_name = 'ACCES'
  10. 10         and owner in ('TEST');
  11. 11  begin
  12. 12    open cur_gather_tab_statistics;
  13. 13    fetch cur_gather_tab_statistics
  14. 14      into vsqlstatement;
  15. 15    while cur_gather_tab_statistics%found loop
  16. 16      execute immediate vsqlstatement;
  17. 17      fetch cur_gather_tab_statistics
  18. 18        into vsqlstatement;
  19. 19    end loop;
  20. 20    close cur_gather_tab_statistics;
  21. 21  end;
  22. 22  /
  23. declare
  24. *
  25. 第 1 行出现错误:
  26. ORA-00900: 无效 SQL 语句
  27. ORA-06512: 在 line 16

  28. SQL>
复制代码


没法贴图,这是我的运行结果,从 bell 回复里拷贝的,为了防止表太多就加了个条件取一个表,不管是过程里还是SqlPlus里,都是一样的结果。

首先,肯定不是权限问题,我用的是SYS,而且生成的语句在sqlplus是可以单独运行的:
exec dbms_stats.gather_table_stats(ownname => 'TEST',tabname =>'ACCES',estimate_percent => 20,cascade => TRUE,force => TRUE);
结果是:PL/SQL 过程已成功完成。

还要确保TEST用户中有表,否则过程里执行不到execute immediate这句,就不会报错。

使用道具 举报

回复
论坛徽章:
1
优秀写手
日期:2014-07-09 06:00:13
26#
 楼主| 发表于 2017-1-12 08:46 | 只看该作者
改成
execute immediate 'begin ' || vsqlstatement || 'end;';
之后成功了。

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
27#
发表于 2017-1-12 10:12 | 只看该作者
aniven 发表于 2017-1-12 08:46
改成
execute immediate 'begin ' || vsqlstatement || 'end;';
之后成功了。

sqlplus的exec命令就是外面套一个begin end

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
28#
发表于 2017-1-12 10:13 | 只看该作者
lastwinner 发表于 2017-1-11 14:43
错误是啥?
不过看7楼的吧,我们自己写代码也是7楼那样就行

剑破里就有动态pl/sql例子

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
29#
发表于 2017-1-12 10:17 | 只看该作者
〇〇 发表于 2017-1-12 10:12
sqlplus的exec命令就是外面套一个begin end

SQL> exec execute immediate 'select * from dual' into a;
BEGIN execute immediate 'select * from dual' into a; END;

                                                  *
第 1 行出现错误:
ORA-06550: 第 1 行, 第 51 列:
PLS-00201: 必须声明标识符 'A'
ORA-06550: 第 1 行, 第 7 列:
PL/SQL: Statement ignored

使用道具 举报

回复
论坛徽章:
169
SQL数据库编程大师
日期:2016-01-13 10:30:43SQL极客
日期:2013-12-09 14:13:35SQL大赛参与纪念
日期:2013-12-06 14:03:45最佳人气徽章
日期:2015-03-19 09:44:03现任管理团队成员
日期:2015-08-26 02:10:00秀才
日期:2015-07-28 09:12:12举人
日期:2015-07-13 15:30:15进士
日期:2015-07-28 09:12:58探花
日期:2015-07-28 09:12:58榜眼
日期:2015-08-18 09:48:03
30#
发表于 2017-1-12 11:23 | 只看该作者
newkid 发表于 2017-1-11 22:59
这是动态PLSQL不是动态SQL, 所以要构造匿名块,即放在BEGIN END; 之间。

楼主可以结帖了,标准答案在这里。别人再看到就可以不用爬楼了。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表