SQL Server中的OBJECT_ID
函数对于使用调用该函数/过程的名称解析规则解析不完全限定的对象名称非常有用。例如,如果我调用SP名称foobar
, T-SQL将首先查看当前用户模式,然后查看dbo
模式。如果它们都有一个foobar
SP,那么将调用用户模式中的那个。OBJECT_ID
函数以同样的方式解析为对象id。
对于Oracle来说,事情要复杂得多,因为还有一个包名的概念。因此,例如doe.foobar
可以引用具有过程foobar
的包doe
,或者它可以引用具有过程foobar
的用户模式doe
。Oracle使用了一些规则(也包括同义词),但我似乎找不到一个函数,可以让我既可以解析Oracle编译器的名称,也可以获得与Oracle编译器找到的匹配的对象id。
所以在所有这些之后,我的问题是:有没有一些方法可以做到这一点,而不试图重新创建Oracle内部使用的名称解析规则?
我可能没有理解这个问题,但是-这是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>
这是一个不接受任何参数并返回字符串的函数
找不到这样做的内置方式,所以我们最终使用三个查询之一,取决于我们是否有…, . 或。唯一复杂的是。这是一个模棱两可的例子。我们最终得到了这个查询,它遵循了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可以改变他们的名称解析规则,我们现在必须跟踪并复制他们正在做的事情。