0

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

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

因此,在所有这些之后,我的问题是:是否有某种方法可以在不尝试重新创建 Oracle 内部使用的名称解析规则的情况下做到这一点?

4

2 回答 2

0

我可能不明白这个问题,但是 - 这就是 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>

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

于 2021-08-05T16:42:13.443 回答
0

找不到这样做的内置方式,所以我们最终得到三个查询之一,具体取决于我们是否有 .., . 或者 。唯一复杂的是 . 这是模棱两可的情况。我们最终得到了这个查询,它遵循 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 可以更改他们的名称解析规则,我们现在必须跟踪并复制他们正在做的事情。

于 2021-08-12T04:17:04.013 回答