为什么 Oracle 12c 中的数据字典中缺少我的 pl sql 代码?

Why is my plsql code missing in the datadictionary in Oracle 12c?

任何人都可以阐明我的 12c 笔记本电脑安装可能有什么问题导致以下问题吗?

简而言之:我在我的模式中创建的所有代码都在那里并且可以执行,但不能在任何 IDE 或通过 dba_source 查看或编辑。

首先:我不是 DBA,也永远不会是,尽管我对 DBA 有所了解。
我是 Oracle 开发人员。所以我可以在安装 12c 时做各种愚蠢的事情。

我已经在笔记本电脑上安装了 Oracle Database 12c 企业版 12.1.0.1.0 64 位。
1 个容器数据库。
1 可插拔数据库。

当我在任何 IDE(pl/sql 开发人员。sql 开发人员,...)中登录我的可插入数据库时​​,我的所有对象都在 'browser' 的 IDE 选择。
但是,当我尝试打开(查看源代码)基于 plsql 的对象(如包/过程/函数/类型)时,我无法打开。
一个例外是触发器。可以查看和编辑它们。
plsql 开发人员 (10.0.5.1710) 告诉我(例如):“/* PACKAGE ERO$UTL 的来源不可用 */”
sql 开发人员 (4.0.3.16) 刚刚向我显示:"create or replace "。

不过对象是可以正常使用的。

一开始我以为"plsql developer just isn't ready for 12c yet"
但是后来我看到 sqldev 也这样做了,所以....

我检查了 database/datadictionary 本身。

我创建了一个简单的程序:

ERO@EVROCS>CREATE OR REPLACE PROCEDURE hi_there  
  2  AS  
  3  BEGIN  
  4    dbms_output.put_line ('Hello World');  
  5  END;  
  6  /  

Procedure created.  

到目前为止一切顺利。
它存在并起作用吗?

ERO@EVROCS>exec hi_there  
Hello World  

PL/SQL procedure successfully completed.  

显然是这样。

现在,user_objects知道它的存在吗?

ERO@EVROCS>SELECT object_name||' - '||object_type   object  
  2  FROM   user_objects  
  3  WHERE  object_name = 'HI_THERE';  

OBJECT  
-----------------------------------------------------------  

HI_THERE - PROCEDURE  

1 row selected.  

是的!太棒了!
现在,告诉我它的来源

ERO@EVROCS>SELECT *  
  2  FROM   user_source  
  3  WHERE  name = 'HI_THERE'  
  4  ;  

no rows selected  

请问?我是不是把名字拼错了?

ERO@EVROCS>SELECT *  
  2  FROM   user_source  
  3  ;  

no rows selected  

没有。

dba_source 也没有显示我的任何来源:

ERO@EVROCS>SELECT DISTINCT  
  2         owner  
  3  FROM   dba_source  
  4  order by owner  
  5  ;  

OWNER  
-------------------------------  

APEX_040200  
CTXSYS  
DBSNMP  
DVF  
DVSYS  
FLOWS_FILES  
GSMADMIN_INTERNAL  
LBACSYS  
MDSYS  
OLAPSYS  
ORACLE_OCM  
ORDPLUGINS  
ORDSYS  
OUTLN  
SYS  
SYSTEM  
WMSYS  
XDB  

18 rows selected.  

我迷路了


新信息:

我认为这与问题无关,但无论如何我都应该提到它:
在 Windows 笔记本电脑上 运行。
Windows 8.1 更准确。

@Lalit
看来你说的有道理。
dbms_metadata 正确生成了我所有对象的代码。

ERO@EVROCS>SELECT dbms_metadata.get_ddl ('PROCEDURE'  
  2                               ,'HI_THERE'  
  3                               ,'ERO'  
  4                               )         statement  
  5  FROM dual;  

STATEMENT  
---------------------------------------------------------------  
  CREATE OR REPLACE EDITIONABLE PROCEDURE "ERO"."HI_THERE"  
AS  
BEGIN  
  dbms_output.put_line ('Hello World');  
END;  

1 row selected.  

1但不知何故数据字典视图看不到我的代码。

@all
调查观点,越看越奇怪
以下摘要:dba_source 不知道我的代码的存在,但组成 dba_source 的源代码知道!!
拉里以神秘的方式移动!

dba_source的来源是:

CREATE OR REPLACE  
VIEW dba_source  
AS  
SELECT OWNER, NAME, TYPE, LINE, TEXT, ORIGIN_CON_ID  
FROM   INT$DBA_SOURCE  
;  

非常简单:视图 INT$DBA_SOURCE.
中的每一行都只是 select 因此,如果视图有任何问题,那一定是在这个(或更深层次)中。

让我们查询该视图,在 PDB 上以 SYSTEM AS SYSDBA 身份登录(因为显然我的 ERO 帐户无法直接查询此类视图)
我知道,我知道,我应该 never 这样登录,但是,数据库启动了 ;-) 所以,我想这是 never

SYS@EVROCS>SELECT s.text  
  2  FROM   INT$DBA_SOURCE  s  
  3  WHERE  s.name  = 'HI_THERE'  
  4  ORDER BY s.line  
  5  ;  

no rows selected  

好的,符合预期。因为这基本上与 dba_source.
相同 INT$DBA_SOURCE 视图有什么作用?

CREATE OR REPLACE  
VIEW int$dba_source  
     (owner  
     ,name  
     ,type  
     ,type#  
     ,line  
     ,text  
     ,sharing  
     ,origin_con_id  
     )  
AS  
SELECT u.name  
,      o.name  
,      DECODE(o.type#  
             , 7, 'PROCEDURE'  
             , 8, 'FUNCTION'  
             , 9, 'PACKAGE'  
             ,11, 'PACKAGE BODY'  
             ,12, 'TRIGGER'  
             ,13, 'TYPE'  
             ,14, 'TYPE BODY'  
             ,22, 'LIBRARY'  
             ,87, 'ASSEMBLY'  
             ,'UNDEFINED'  
             )  
,      o.type#  
,      s.line  
,      s.source  
,      DECODE(bitand(o.flags, 196608)  
             ,65536 , 1  
             ,131072, 1  
             ,0  
             )  
,      TO_NUMBER(sys_context('USERENV', 'CON_ID'))  
FROM   sys."_CURRENT_EDITION_OBJ"     o  
,      sys.source$                    s  
,      sys.user$                      u  
WHERE  o.obj#               = s.obj#  
  AND  o.owner#             = u.user#  
  AND  (   o.type#         IN (7, 8, 9, 11, 12, 14, 22)  
        OR (    o.type#     = 13  
            AND o.subname  IS NULL  
           )  
       )  
UNION ALL  
SELECT u.name  
,      o.name  
,      'JAVA SOURCE'  
,      o.type#  
,      s.joxftlno  
,      s.joxftsrc  
,      DECODE(bitand(o.flags, 196608)  
             ,65536 , 1  
             ,131072, 1  
             ,0  
             )  
,      TO_NUMBER(sys_context('USERENV', 'CON_ID'))  
FROM   sys."_CURRENT_EDITION_OBJ"     o  
,      x$joxscd                       s  
,      sys.user$                      u  
WHERE  o.obj#       = s.joxftobn  
  AND  o.owner#     = u.user#  
  AND  o.type#      = 28  
;  

好的!
我明白了。所以基本上是从用户到对象再从那里到源的连接。
然后对象需要是某种类型。
也许我对象的 'type' 是错误的?
第一个问题我的用户是什么#

SYS@EVROCS>SELECT u.user#  
  2  FROM   sys.user$  u  
  3  WHERE  u.name = 'ERO'  
  4  ;  

          USER#  
---------------  
            111  

1 row selected.  

我有一个用户号,所以我...
现在对象是否存在,如果存在,它的 obj#、类型和子名称是什么(where 子句中的内容)?

SYS@EVROCS>SELECT o.obj#  
  2  ,      o.name  
  3  ,      o.type#  
  4  ,      NVL(o.subname,'<<NULL>>')  subname  
  5  FROM   sys."_CURRENT_EDITION_OBJ" o  
  6  WHERE  o.owner# = 111  
  7    AND  o.name   = 'HI_THERE'  
  8  ;  

  OBJ# NAME      TYPE# SUBNAME  
------ --------- ----- ---------  
 97193 HI_THERE      7 <<NULL>>  

1 row selected.  

是的,它存在。
type/subname 组合是 where 子句除外的组合。
所以问题一定在sys.source$.
很明显,那个人没有提供源....

SYS@EVROCS>SELECT s.source  
  2  FROM   sys.source$   s  
  3  WHERE  s.obj#  = 97193  
  4  ORDER BY s.line  
  5  ;  

SOURCE  
---------------------------------------------  
PROCEDURE hi_there  
AS  
BEGIN  
  dbms_output.put_line ('Hello World');  
END;  

5 rows selected.  

什么????
来源在那里。
我刚刚检查了视图源的每个部分。它检查正常。
所以视图的 select 语句应该产生我的过程的来源。
但如果是这样,从视图中 selecting 也应该如此。

所以,虽然我知道它不能给我我的源代码(因为视图没有),但我会检查如果我从 select 语句中 select 会发生什么视图的来源

SYS@EVROCS>SELECT SOURCE  
  2  FROM   (  
  3  SELECT u.name       u_name  
  4  ,      o.name       o_name  
  5  ,      DECODE(o.type#  
  6               , 7, 'PROCEDURE'  
  7               , 8, 'FUNCTION'  
  8               , 9, 'PACKAGE'  
  9               ,11, 'PACKAGE BODY'  
 10               ,12, 'TRIGGER'  
 11               ,13, 'TYPE'  
 12               ,14, 'TYPE BODY'  
 13               ,22, 'LIBRARY'  
 14               ,87, 'ASSEMBLY'  
 15               ,'UNDEFINED'  
 16               )  
 17  ,      o.type#  
 18  ,      s.line  
 19  ,      s.source  
 20  ,      DECODE(bitand(o.flags, 196608)  
 21               ,65536 , 1  
 22               ,131072, 1  
 23               ,0  
 24               )  
 25  ,      TO_NUMBER(sys_context('USERENV', 'CON_ID'))    u_env  
 26  FROM   sys."_CURRENT_EDITION_OBJ"     o  
 27  ,      sys.source$                    s  
 28  ,      sys.user$                      u  
 29  WHERE  o.obj#               = s.obj#  
 30    AND  o.owner#             = u.user#  
 31    AND  (   o.type#         IN (7, 8, 9, 11, 12, 14, 22)  
 32          OR (    o.type#     = 13  
 33              AND o.subname  IS NULL  
 34             )  
 35         )  
 36  UNION ALL  
 37  SELECT u.name  
 38  ,      o.name  
 39  ,      'JAVA SOURCE'  
 40  ,      o.type#  
 41  ,      s.joxftlno  
 42  ,      s.joxftsrc  
 43  ,      DECODE(bitand(o.flags, 196608)  
 44               ,65536 , 1  
 45               ,131072, 1  
 46               ,0  
 47               )  
 48  ,      TO_NUMBER(sys_context('USERENV', 'CON_ID'))  
 49  FROM   sys."_CURRENT_EDITION_OBJ"     o  
 50  ,      x$joxscd                       s  
 51  ,      sys.user$                      u  
 52  WHERE  o.obj#       = s.joxftobn  
 53    AND  o.owner#     = u.user#  
 54    AND  o.type#      = 28  
 55  )  
 56  WHERE o_name = 'HI_THERE'  
 57  ORDER BY line  
 58  ;  

SOURCE  
----------------------------------------------------------------------  

PROCEDURE hi_there  
AS  
BEGIN  
  dbms_output.put_line ('Hello World');  
END;  

5 rows selected.  

荷兰有一些烂东西:-(

老实说,我从未听说过这样的问题,也无法重现。所以,我不能告诉你奇怪行为的原因。

但是,除了其他 PL/SQL 代码之外,您可以看到 trigger 代码这一事实,我确信 user_source 视图可能存在问题。由于 *_source 视图中不包含触发器。我搜索了 MOS,找不到与您的问题相关的任何内容。

替代 user_source 获取您的程序的源代码,您可以尝试 dbms_metadata -

select dbms_metadata.get_ddl('PROCEDURE','PROCEDURE_NAME','USERNAME') from dual;

看看你是否得到一些结果会很有趣。

上周我有幸有机会与 Tom Kyte 交谈。 因为他是 AskTom 的 Tom,所以我就这么做了:我问他这个问题。 我解释了我上面写的,然后问他:"what did I do wrong?"

他的回答简单明了:"Probably nothing"。 他解释说 12.1.0.1 在数据字典视图中有几个错误,因为突然之间他们不得不从容器数据库和插件数据库中获取一部分数据。 所以,Tom 得出结论,我可能 运行 遇到了一个软管错误。

尽管如此,由于没有人能够证实这种行为,而且由于我无法想象自己是唯一一个使用 12.1.0.1 数据库的人,所以我觉得一定是我做了一些事情导致这个错误被注意到。

无论如何,既然我确定问题可能出在产品上,我将停止进一步调查并升级到 12.1.0.2。 现在,如果升级使问题消失,我相信它不会在我重复 12.1.0.1 的愚蠢行为后一周后再次出现。

编辑 25/02:

上周末按照与安装 12.1.0.1 时完全相同的步骤卸载了 12.1.0.1 并安装了 12.1.0.2。 问题消失了。 所以看起来汤姆是对的(再一次)。