PL/SQL使用哪种类型的绑定?

jop*_*hab 14 sql oracle binding plsql

我遇到了以下问题.

PL/SQL使用以下哪项

  • (A)没有约束力
  • (B)早期结合
  • (C)晚期绑定
  • (D)延迟绑定

但找不到任何令人满意的答案.

有人能解释一下吗?

Jon*_*ler 15

(E)以上所有

这是一个荒谬的多项选择题.术语早期,晚期和延迟绑定是模糊的.PL/SQL可以以多种不同的方式运行,包括在SQL中.

以下是我(可以说是不正确的)选择的定义:

  1. 没有绑定 - 变量没有类型.
  2. 早期绑定 - 变量类型在编译时固定.
  3. 后期绑定 - 变量类型是灵活的,可以在运行时设置.
  4. 延迟绑定 - 在编译时定义多个变量类型,但在运行时只选择其中一个.

现在我们必须将这些选择与不同的PL/SQL上下文相匹配:静态SQL和PL/SQL,空匿名块,远程过程,动态SQL和PL/SQL,自适应游标共享,FILTER操作,面向对象的PL/SQL,ANY*类型,我可能会错过更多.

(A)没有约束力

空匿名块没有任何变量,因此没有任何约束.我不确定这是否真的符合无绑定的定义,它似乎有点像边缘情况.在某些语言中总是有一个对象,必须始终绑定一些东西,但不能在PL/SQL中绑定.

(B)早期结合

常规SQL和PL/SQL使用早期绑定 - 给变量一个类型,他们必须坚持它.类型不匹配将导致编译器错误或需要隐式转换.

REMOTE_DEPENDENCIES_MODE设置为"TIMESTAMP"的远程过程调用可以说是早期绑定.检查所有内容时,时间戳在编译时设置.这仍然检查在运行时,但它是一个简单,快捷的检查.

(C)晚期绑定

动态SQL和PL/SQL使用后期绑定,因为代码甚至在运行时都没有编译.这适用于DBMS_SQLexecute immediate.

面向对象的PL/SQL使用后期绑定.类型在编译时设置,但在运行时可以使用不同的子类型.

ANYTYPE,ANYDATA和ANYDATASET也使用后期绑定,因为它们可以在运行时创建,也可以在运行时检索和执行.

REMOTE_DEPENDENCIES_MODE设置为"SIGNATURE"的远程过程调用可以说是后期绑定.在编译时和运行时检查签名,并允许类型的一点点灵活性.

(D)延迟绑定

某些Oracle SQL功能会创建多个代码路径,但只执行其中一个.自适应游标共享和FILTER操作将创建多种方法来运行相同的SQL语句,并在运行时选择适当的版本.


祈求者的权利和定义者的权利

祈求者的权利和定义者的权利也使这个问题复杂化.但我认为最终它们并没有什么不同,而且它们都仍然具有早期约束力.编译器仍然在编译时决定类型.虽然您可以使用调用者的权限在运行时隐秘地更改类型,但它只会生成错误,因为它与预期的类型不匹配.

例如,假设有两个模式具有相同的表名和列名,但是不同的类型:

create table user1.test_table(a number);
insert into suer1.test_table values(1);

create table user2.test_table(a date);
insert into user2.test_table values(sysdate);
Run Code Online (Sandbox Code Playgroud)

如果您在USER1上创建此功能,它看起来像是V_VALUE动态的类型,可以随用户更改.

create or replace function user1.test_function return varchar2 authid current_user is
    v_value test_table.a%type;
begin
    select a into v_value from test_table;
    return to_char(v_value);
end;
/
Run Code Online (Sandbox Code Playgroud)

代码使用类型编译,USER1并在USER1运行时正常工作.但是,当USER2运行它时会生成以下错误:ORA-00932: inconsistent datatypes: expected NUMBER got DATE.

这让我相信调用者和定义者的权利不会影响绑定.它们都在静态SQL和PL/SQL中使用早期绑定.

  • 通过添加"调用者权限"以及它们如何影响绑定,可以改善您的非常好的答案. (4认同)

kro*_*lko 11

您可以在与Oracle 8相关的非常旧的文档中找到答案:https:
//docs.oracle.com/cd/A58617_01/server.804/a58236/05_ora.htm

效率与灵活性

在执行PL/SQL程序之前,必须对其进行编译.PL/SQL编译器通过在数据字典中查找它们的定义来解析对Oracle模式对象的引用.然后,编译器将存储地址分配给将保存Oracle数据的程序变量,以便Oracle可以在运行时查找地址.此过程称为绑定.

数据库语言如何实现绑定会影响运行时效率和灵活性.在编译时绑定(称为静态或早期绑定)可提高效率,因为架构对象的定义会在运行时查找,而不是在运行时查找.另一方面,在运行时绑定(称为动态或后期绑定)会增加灵活性,因为在此之前架构对象的定义可能仍然未知.

PL/SQL主要用于高速事务处理,它通过捆绑SQL语句和避免运行时编译来提高效率.与SQL不同,SQL是在运行时逐个语句编译和执行的(后期绑定),PL/SQL在编译时被处理成机器可读的p代码(早期绑定).在运行时,PL/SQL引擎只执行p代码.

但是后续版本中的Oracle从文档中删除了整个与Oracle交互的章节.

因此,根据上面的答案是:(B)早期绑定 - 对于Oracle版本8,以及可能在更进一步的版本中肯定.

  • Oracle在04-OCT-2016上最后更新的Oracle支持文档1008453.6重申了这一点:_PL/SQL使用静态或早期绑定.这意味着绑定在编译时完成,这提高了效率,因为数据库对象的定义是在编译时查找的,而不是在运行时查找.如其他人所指出的,有很多例外,但早期绑定是基本的方式PL/SQL似乎有效. (3认同)