我可以在调用同一过程后将 PL/SQL 过程放在匿名块中吗?
Posted
技术标签:
【中文标题】我可以在调用同一过程后将 PL/SQL 过程放在匿名块中吗?【英文标题】:Can I drop PL/SQL procedure in Anonymous block just after called the same procedure? 【发布时间】:2020-10-12 00:25:51 【问题描述】:我创建了一个 PL/SQL 存储过程,用于将行插入到相关表中,然后在另一个 PL/SQL 匿名块中,我可以单独调用和删除它。但是,当把这两个语句放在一起时,Sql developer 只是永远持续在那里运行。下面是三个代码sn-ps:
-- 下面的代码运行良好
BEGIN
MyProcedure1 (1,70,'Tommy');
END;
-- 下面的代码运行良好
BEGIN
EXECUTE IMMEDIATE 'drop procedure MyProcedure1';
END;
-- 下面的代码永远卡在那里
BEGIN
MyProcedure1 (1,70,'Tommy');
EXECUTE IMMEDIATE 'drop procedure MyProcedure1';
END;
【问题讨论】:
我想不出你想要这样做的任何场景,如果你能提供一些背景信息来说明你为什么要这样做,那将会很有帮助。这可能使人们能够就如何以不同方式/更好地实现您的目标向您提出建议。 我有一批记录要插入到具有特定过程的表中,这是客户的要求。程序没有问题。所以我只需要写一个新的脚本来用这个程序插入相关数据,并且在插入所有这些行之后,我还想在同一个脚本中删除这个特定的程序,然后遇到上述问题。 其实我做过一个相关的测试:我创建了另外一个程序(很简单,甚至没有任何参数),然后在另一个脚本中(必须有Begin和End,相关语句就定位它们之间),我调用这个新程序然后使用“立即执行”dropt 程序----然后结果是一样的,代码卡在那里! 所以问题很简单:在PL/SQL的匿名块中,我们可以调用一个过程然后使用EXECUTE IMMEDIATE删除它吗? --- 此代码与具体业务逻辑无关 基本上每个人都可以在自己的环境中测试两分钟 【参考方案1】:David,我仍然看不出为什么在插入数据后您需要立即删除该过程....如果您想明天插入更多数据怎么办?如果它只是一次性的东西,为什么你不能事后手动删除它?
但是如果你真的必须这样做......
BEGIN
MyProcedure1 (1,70,'Tommy');
END;
/
drop procedure MyProcedure1;
然后单击 SqlDeveloper 中的 run as script 按钮...运行没有问题,查看会话管理器正在发生的事情是匿名块将过程放入缓存/固定它(意味着没有其他东西可以编译/删除它)直到该块完成。这就是为什么将 drop 移到 Begin / End 之外允许代码工作的原因。
【讨论】:
嗨,肖恩,感谢您的解决方案和解释!该程序只是为了插入这个批次数据,客户不希望运行两个脚本来完成一个任务。【参考方案2】:如果你查询v$session
,这就是你所看到的(当然,当匿名 PL/SQL 块仍在“运行”时——实际上,它正在等待):
SQL> select
2 a.blocking_session,
3 b.username blocking_username,
4 b.osuser blocking_osuser,
5 a.sid,
6 a.serial#,
7 a.seconds_in_wait,
8 a.username,
9 a.wait_class,
10 a.state
11 from v$session a join v$session b on a.blocking_session = b.sid;
BLOCKING_SESSION BLOCKING_USERNAME BLOCKING_OSUSER SID SERIAL# SECONDS_IN_WAIT USERNAME WAIT_CLASS STATE
---------------- ----------------- --------------- ---- -------- --------------- -------- ----------- -------
707 SCOTT littlefoot 707 1245 329 SCOTT Concurrency WAITING
SQL>
注意最后两列:
state
= 等待
wait_class
= 并发
是谁造成的?我自己。所以是的 - 我们遇到了敌人,他们就是我们。
看起来你不能按照你想要的方式做,而是分开做:
先调用过程 完成后,放下它不过,多么奇怪的要求……你为什么要放弃一个程序? 明天你会再次创建它吗?如果是这样,为什么要放弃它?说“客户需要它”——客户到底知道什么?让他们三思而后行;如果这还不够,请再想一想。
【讨论】:
您好 Littlefoot,感谢您的解释!该程序只是为了插入这批数据,客户不想运行两个脚本来完成一个任务。以上是关于我可以在调用同一过程后将 PL/SQL 过程放在匿名块中吗?的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 PL/SQL 开发人员测试窗口的“声明”块中声明子过程?
ORACLE PL/SQL:以最大执行时间调用外部 Oracle PL/SQL 过程