AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 79448676
Accepted
Zahrada
Zahrada
Asked: 2025-02-18 22:54:15 +0800 CST2025-02-18 22:54:15 +0800 CST 2025-02-18 22:54:15 +0800 CST

为什么 PL/SQL 包状态没有重置?

  • 772

当抛出 ORA 时,我遇到了包初始化状态的奇怪行为。这是我在 Oracle 12c 上运行的示例:

create or replace package pkg is
   v_num number := pkg_two.getnum_two;
   function getnum return number;
end;

create or replace package pkg_two is
   v_num_two number := 1;
   
   function getnum_two return number;
end;

create or replace package body pkg is
   function getnum return number is
   begin
      return v_num;
   end;
end;

create or replace package body pkg_two is
   function getnum_two return number is
   begin
      return v_num_two;
   end;
begin
   dbms_lock.sleep(10);
end;

现在出现了奇怪的行为。我在 SQLPlus 中运行以下代码,并在 5 秒后中断它:

declare
   v_number number;
begin
   select pkg.getnum into v_number from dual;
   dbms_output.put_line('output: ('||v_number||')');
end;

此中断抛出了 ORA-01013。然后我再次运行它,仅几毫秒后我就得到了:

output: ()

这很奇怪,因为在 12c 中,只有在初始化完成后才应将包设置为初始化,正如我在本文中发现的那样:https://rogertroller.com/2018/05/16/package-initialization-changes-between-oracle-11g-and-oracle-12c/

同样奇怪的是,如果我用“:=”替换“SELECT INTO”,则行为正如文章所述:

declare
   v_number number;
begin
   v_number := pkg.getnum;
   dbms_output.put_line('output: ('||v_number||')');
end;

因此,在执行两次相同的运行程序后,我得到(第二次运行后 10 秒):

output: (1)

有人能解释一下这种行为是否是预期的吗?如果是,不使用“SELECT INTO”子句是否会发生这种情况?

plsql
  • 1 1 个回答
  • 39 Views

1 个回答

  • Voted
  1. Best Answer
    Alex Poole
    2025-02-19T00:27:49+08:002025-02-19T00:27:49+08:00

    我没有看到您在 19c 中描述的行为,因此自您引用的文章中的更改以来,它大概已经进行了进一步修改。目前尚不清楚这是在描述 12cR1 还是 12R2,因为它被标记为两者;但这篇类似的文章和Steven Feuerstein 的LiveSQL 演示指出它最初在 12cR1 中发生了变化。它可能在这两个版本之间、18c 或 19c 中或两者之间的某个补丁中发生了进一步变化。您还没有说您在哪个版本和补丁集上看到了行为上的差异。

    无论如何...版本执行以下操作:

    v_number := pkg.getnum;
    

    似乎表现得和你预期的一样,与文章所说的一致。该版本完全是 PL/SQL - 您正在调用包函数并将其返回值直接分配给 PL/SQL 变量,因此不涉及 SQL。

    执行的版本:

    select pkg.getnum into v_number from dual;
    

    表现不同(对您而言,但在 19c 中不是),但在 PL/SQL 和 SQL 之间有上下文切换。select into...本质上是退出 PL/SQL 来执行 SQL 语句,并将结果返回到 PL/SQL 变量中。(我想如果您直接select pkg.getnum from dual在 SQL 中执行此操作,而不使用匿名块,您会看到同样的事情?)

    这表明对初始化行为的更改最初以不同的方式处理。无论使用何种机制来保持包未初始化(或未实例化),或者可能将其恢复到该状态,当会话中发生异常时,似乎只适用于在 PL/SQL 上下文中看到的情况。早期的迭代似乎忽略了 SQL 上下文中发生的相同事情。而一些后续补丁或版本对其进行了改进,使其在两种上下文中以相同的方式工作。(通常都是这样 - 错误 34969407 表明它可能仍然不完全一致。)知道它究竟是什么时候改变的会很有趣。

    这必然是猜测,部分原因是我没有 12c DB 可以再次测试,也是因为我看不到关于为什么更改它或者它内部如何运作的任何细节 - 这不是我所期望的 - 或者该领域的任何文档更改。

    由于在后续版本中已修复或至少改进了此问题,因此我不会说行为上的差异是“预期的”,因为它看起来不像是故意的。不过,根据您所看到的情况,我预计会在 12cR1 以及可能的一些后续版本/补丁集中看到此问题,但不会在较新的版本中看到。即使如此,也可能只有在涉及上下文切换时才会出现。

    • 3

相关问题

  • PL/SQL 块内的 SQL 查询无法正常工作,获取所有数据并忽略 WHERE 子句

  • 比较游标值是否存在于另一个游标中 - oracle plsql

  • 匿名块中的 PL/SQL 记录类型

  • PL/SQL 代码中带有 IN 运算符的 IF 语句

  • 执行下一条sql语句

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve