? ?因爲公司的數據庫是以Oracle為主的 最近在整理oracle對象以來的查詢的内容,今天做個小總結。先介紹下實驗環境是oracle11g。
? 首先復習下在 Oracle 数据库中,对象的编译过程通常遵循以下流程:
语法检查:首先,Oracle 数据库会对你提交的代码进行语法检查,确保它符合 PL/SQL 或 SQL 的语法规范。如果存在语法错误,编译过程会被中断,并返回相应的错误信息。
语义检查:在通过语法检查后,Oracle 数据库会进行更严格的语义检查。这一步骤会验证对象引用的表、列、视图等是否存在,并检查授权权限是否足够。如果存在语义错误,编译过程也会被中断,并返回相应的错误信息。
编译生成中间代码:在通过前两个步骤的检查后,Oracle 数据库会将代码编译为中间代码(Intermediate Representation),这是一种特定于数据库的内部表示形式。这个中间代码是数据库在执行时所使用的形式。
优化执行计划:在编译过程中的一个关键步骤是优化执行计划。Oracle 数据库会对查询语句进行优化,选择最有效的执行计划,以提高查询性能。这包括选择最佳的索引、连接顺序等。
生成可执行代码:在完成优化后,Oracle 数据库会根据中间代码生成最终的可执行代码。这些可执行代码可以直接在数据库中执行。
存储可执行代码:编译完成后,Oracle 数据库会将生成的可执行代码存储在数据库的数据字典中。这样,在下次执行相同的对象时,数据库可以直接使用已编译的代码,提高执行效率。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ???
? ? ?簡單來説就是oracle會 進行語法/語意檢查之後,編譯優化語法,生成可執行代碼,執行並保存在數據字典中,下次將直接從數據字典獲取可執行代碼,這樣可以減少編譯時間,提高執行效率。
? ? ?我們都知道oracle的存儲過程/函數的創建語法,但在實際的生產中,在我們修改這些procedure和function之後,還需要進行數據庫層級對依賴這些對象的對象的進行重新編譯。
? ? ?比如說,B引用A之後,?A修改后會被數據庫自動打為invalid,引用A的B的也會被打為invalid,程序執行B的時候發現B是invalid,會重新編譯,但是因爲A是invalid,會導致B也跟著失敗,異常由此產生。
? 因为oracle的对象存在互相调用的情况,因此重新编译之前需要对对象的历来进行评估,这些代表了所有的对象都需要进行重新编译,在数据库繁忙的时候,有可能因为你编译object过多,导致编译时长过长,而导致设备卡死。
level代表了依赖调用的级别1级别代表直接调用,二级间接调用,由此类推。
select level,'alter '||decode(type,'PACKAGE BODY',
'PACKAGE',type)||' '||name||' '||
decode(type,'PACKAGE BODY','compile body','compile')||';'
from user_DEPENDENCIES
start with REFERENCED_NAME=upper('A')
connect by nocycle prior name= REFERENCED_NAME
order by level
小技巧
? 我们如果修改object的时候,想直观看到自己的修改的object是如何被其他object调用的,可以使用此语法来观察
SELECT * FROM user_source
WHERE TYPE = 'PROCEDURE'
AND upper(text) LIKE upper('%A%');
?
? ? ?正如前面A因为被B依赖,导致A需要进行重新的compile,这由此导致了另一个问题,当会话未activate的时候,procedure会被锁住,这样将直接导致编译失败,间接导致机台停机。以下语法是判断当前的procedure被哪些设备调用,评估设备重启的影响。
select status, terminal ,username
from v$session
where sid in (
select session_id from dba_ddl_locks
where name=upper('A'))
V$SESSION
视图中的字段名及其含义如下:
AUDSID
:会话的唯一标识符。USER#
:用户 ID,对应于?DBA_USERS
?视图中的?USER_ID
?字段。USERNAME
:用户名。USERHOST
:与会话关联的客户端计算机名称。TERMINAL
:与会话关联的终端设备名称。PROGRAM
:正在使用该会话的程序名称。OSUSER
:操作系统用户名称。PROCESS
:Oracle 进程 ID。MACHINE
:与该会话关联的客户端计算机名称。PORT
:客户端使用的端口号。LOGON_TIME
:会话的登录时间。LAST_CALL_ET
:从上次 SQL 语句调用以来经过的时间(以秒为单位)。SQL_HASH_VALUE
:执行的 SQL 语句的哈希值。SQL_ID
:执行的 SQL 语句的 SQL_ID。PREV_SQL_HASH_VALUE
:上一个执行的 SQL 语句的哈希值。PREV_SQL_ID
:上一个执行的 SQL 语句的 SQL_ID。STATUS
:会话状态,如 ACTIVE、INACTIVE、KILLED 等。SERVER
:指示会话是否使用了共享服务器(SHARED)或独立服务器(DEDICATED)的标志。SCHEMA#
:正在使用的模式的 ID,对应于?DBA_USERS
?视图中的?DEFAULT_TABLESPACE
?字段。SCHEMANAME
:正在使用的模式名称。MODULE
:应用程序模块名称。MODULE_HASH
:应用程序模块名称的哈希值。ACTION
:应用程序操作名称。ACTION_HASH
:应用程序操作名称的哈希值。CLIENT_INFO
:客户端信息字符串。? ? ? 好,打完收工,下班
??
? ? ??