【问题标题】:Is there an equivalent to the OBJECT_ID function from T-SQL in Oracle?Oracle 中是否有与 T-SQL 中的 OBJECT_ID 函数等效的函数?
【发布时间】:2021-10-10 15:35:43
【问题描述】:

SQL Server 中的OBJECT_ID 函数对于使用适用于调用该函数/过程的名称解析规则来解析不完全限定的对象名称非常有用。例如,如果我调用 SP 名称 foobar,T-SQL 将首先在当前用户模式中查找,然后在 dbo 模式中查找。如果他们都有foobar SP,则将调用用户模式中的那个。 OBJECT_ID 函数以相同的方式解析为对象 id。

不过,对于 Oracle,事情要复杂得多,因为还有包名的概念。因此,例如doe.foobar 可以引用具有过程foobar 的包doe,或者它可以使用过程foobar 引用用户模式doe。 Oracle 使用了rules for this(也包括同义词),但我似乎找不到一个函数可以让我解析 Oracle 编译器的名称或获取与 Oracle 编译器匹配的对象 ID .

所以我的问题是:有没有办法在不尝试重新创建 Oracle 内部使用的名称解析规则的情况下做到这一点?

【问题讨论】:

    标签: sql-server oracle fully-qualified-naming


    【解决方案1】:

    我可能不明白这个问题,但是 - 这就是 Oracle 所做的。我有点懒惰地创建一个名为dbo 的新用户,所以我改用scott,但我想这并不重要。

    当前连接为scott

    SQL> show user
    USER is "SCOTT"
    

    创建一个名为 scott 的包(显然,由 scott 拥有,这意味着它在 scott 架构中)和一个函数 foobar 在其中(返回 我在哪里 ):

    SQL> create or replace package scott as
      2    function foobar return varchar2;
      3  end;
      4  /
    
    Package created.
    
    SQL> create or replace package body scott as
      2    function foobar return varchar2 is
      3    begin
      4      return 'package function';
      5    end;
      6  end;
      7  /
    
    Package body created.
    

    创建一个名为 foobar 的独立函数(同样归 scott 所有):

    SQL> create or replace function foobar return varchar2 is
      2  begin
      3    return 'standalone function';
      4  end;
      5  /
    
    Function created.
    

    好的;那么,当我们逐渐调用它们时会返回什么(foobar > scott.foobar > scott.scott.foobar):

    SQL> select foobar from dual;
    
    FOOBAR
    --------------------------------------------------------------------------------
    standalone function
    
    SQL> select scott.foobar from dual;
    
    FOOBAR
    --------------------------------------------------------------------------------
    package function
    
    SQL> select scott.scott.foobar from dual;
    
    FOOBAR
    --------------------------------------------------------------------------------
    package function
    
    SQL>
    

    因此,没有歧义;规则就是规则。唯一模棱两可的东西(从我个人的角度来看)是由我制作的。到底是什么迫使我创建了一个名为 scott 的包?


    截至对象 ID:这是您要查找的内容吗?

    SQL> select object_name, object_type, object_id
      2  from user_objects
      3  where object_name in ('SCOTT', 'FOOBAR');
    
    OBJECT_NAME  OBJECT_TYPE          OBJECT_ID
    ------------ ------------------- ----------
    FOOBAR       FUNCTION                 25973
    SCOTT        PACKAGE                  25971
    SCOTT        PACKAGE BODY             25972
    
    SQL>
    

    [编辑]

    阅读您的评论后,也许这回答了您的问题(至少,一点点):

    SQL> describe scott.foobar
    FUNCTION scott.foobar RETURNS VARCHAR2
    
    SQL>
    

    所以,这是一个不接受任何参数并返回字符串的函数。

    【讨论】:

    • 并不是我想要的。也许我不清楚我遇到困难的部分:如果我不知道那里有什么并且有人要求我运行 scott.foobar 并且我想获取有关 scott.foobar 的详细信息(例如它的参数),如何找到将被调用的 scott.foobar 的对象 ID?例如,这可能会有所不同,具体取决于我登录的人。对于 SQL Server,OBJECT_ID 函数为我提供了基于当前范围调用的对象 ID。我如何为 Oracle 获得它?
    • 也许是 DESCRIBE 有帮助...请参阅我在答案底部添加的示例。
    • DESCRIBE 是一个 SQL*Plus 命令,它不能从 sql 或 plsql 调用,所以它不起作用。
    • 恐怕我暂时没有其他想法,抱歉。
    【解决方案2】:

    找不到这样做的内置方式,因此我们最终得到三个查询之一,具体取决于我们是否有 .., .要么 。唯一复杂的是 .这是模棱两可的情况。我们最终得到了这个查询,它遵循 Oracle 记录的名称解析:

    SELECT OBJECT_ID, IN_OUT, DATA_TYPE, DATA_LEVEL, ARGUMENT_NAME, POSITION, SEQUENCE, 1 AS PRIORITY FROM USER_ARGUMENTS 
        WHERE PACKAGE_NAME = :pkg AND OBJECT_NAME = :name 
    UNION ALL 
    SELECT OBJECT_ID, IN_OUT, DATA_TYPE, DATA_LEVEL, ARGUMENT_NAME, POSITION, SEQUENCE, 2 AS PRIORITY FROM ALL_ARGUMENTS 
        WHERE OWNER = :pkg AND PACKAGE_NAME IS NULL AND OBJECT_NAME = :name 
    ORDER BY PRIORITY, SEQUENCE
    

    如果你看不出来,争论就是我真正想要的。这不是理想的解决方案,因为 Oracle 可以更改他们的名称解析规则,我们现在必须跟踪并复制他们正在做的事情。

    【讨论】:

      猜你喜欢
      • 2018-10-17
      • 1970-01-01
      • 2017-09-11
      • 2015-12-26
      • 1970-01-01
      • 1970-01-01
      • 2016-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多