我有一个11G的数据库。我需要检查一些存储过程,看看它们是否使用特定的表。(前端和后端sps)我拥有对数据库的完全访问权限,并且我还拥有存储在TFS 上的项目的所有单个sps 的副本。
我想要一种方法来生成与这个特定表交互的所有 sps 的列表。我不熟悉如何去搜索这些。任何人都可以建议获取这些数据的最合乎逻辑的方式吗?
谢谢。
我有一个11G的数据库。我需要检查一些存储过程,看看它们是否使用特定的表。(前端和后端sps)我拥有对数据库的完全访问权限,并且我还拥有存储在TFS 上的项目的所有单个sps 的副本。
我想要一种方法来生成与这个特定表交互的所有 sps 的列表。我不熟悉如何去搜索这些。任何人都可以建议获取这些数据的最合乎逻辑的方式吗?
谢谢。
如果我理解正确,您正在尝试table
在所有存储的过程中搜索 a 的出现。在这种情况下,您可以使用以下查询:
SP
在您的架构中搜索出现时
SELECT * FROM user_source WHERE text LIKE '%tab_name%';
SP
在所有模式中搜索出现时
SELECT * FROM all_source WHERE text LIKE '%tab_name%';
有两件事,在 PL/SQL 中有一些更改需要重新编译 pl/sql 对象,其他则不需要。要看到第一个,您有ALL_DEPENDENCIES
视图。或 DBA_,如果您愿意。
如果只是想查看表名在所有 pl/sql 代码中出现的位置,对表的更改是否需要重新编译,可以使用ALL_SOURCE
大写字母和 %,但可能需要一些时间。
我使用 PLSQL Developer,您可以在其中浏览到表(或其他对象),并查看“引用者”,以查看引用该表的所有对象。这很容易。我可以想象其他工具也有类似的功能。
我不知道这个预先解析的信息是否在 Oracle 中很容易获得,但我可以想象,因为这些工具似乎工作得很快。
此信息在All_DEPENDENCIES
这些工具可能使用的视图中可用。
存储过程的来源可以在USER_SOURCE
(或ALL_SOURCE
)视图中找到,其中存储了整个数据库的结构。然而,从那里获取和解析代码会非常麻烦。
这是我为给定的@schema(仅大写)和@table(仅大写)执行影响分析(仅合并、插入和更新)而编写的片段。它将返回所有过程名称、过程代码、从行号到行号以及其他详细信息。它也可以很容易地用于包含函数对象而不是包。正在开发一个可以跨所有模式或选定模式运行的实用程序(也将包括 SELECT 行)。尽管这足以让您开始工作。
我知道您可以使用 Oracle 中可用的依赖项和引用来执行类似的操作。但是对于包装级别的影响,这是一个很好的补充。我们还可以使用正则表达式进行更复杂的搜索。但是喜欢操作员对我的需求来说既简单又高效。
请注意,这不适用于可能在您的环境中运行的任何动态代码。这只是快速了解包中静态 PL/SQL 代码影响的适当起点。
WITH TableDep as
-- This table returns references where the table is used within the code for UPDATE OR INSERT
(
SELECT
owner as schemaname,
name as packagename,
type as typename,
TEXT as refcodeline,
CASE WHEN upper(text) LIKE '%INSERT%' THEN 'INSERT'
WHEN upper(text) LIKE '%UPDATE%' THEN 'UPDATE'
WHEN upper(text) LIKE '%MERGE%' THEN 'MERGE'
END AS opr,
:Tablename AS Tablename,
line refline
FROM dba_source WHERE upper(owner) = upper(:OWNER)
AND type = 'PACKAGE BODY'
AND (
upper(text) LIKE ('%INSERT INTO '||:Tablename||'%')
OR
upper(text) LIKE ('%UPDATE%'||:Tablename||' %')
OR
upper(text) LIKE ('%MERGE%'||:Tablename||' %')
)
),
ProcedureDetails as
-- This code build all procedures within the package for references that is found in above query
(
SELECT
owner as schemaname,
name as packagename,
type as typename,
TEXT,
trim(REGEXP_SUBSTR(TEXT, '(PROCEDURE [[:print:]]+)\(',1,1,null,1)) as procedure_name,
line startline,
LEAD(line, 1) OVER (partition by name order by line)-1 as endline
FROM dba_source
WHERE owner = upper(:OWNER)
AND type = 'PACKAGE BODY'
AND upper(text) LIKE '%PROCEDURE%(%'
and exists (SELECt 1 FROM TableDep WHERE TableDep.packagename=name)
)
,ProcCode as
-- This code builds procedures into one cell per program for a given package. Later to find the effected procedures
(
SELECT
ProcTag.packagename ,
ProcTag.schemaname,
ProcTag.typename,
ProcTag.PROCEDURE_NAME,
ProcTag.startline,
ProcTag.endline,
TO_CLOB(rtrim(xmlagg(xmlelement(e,codeline.text).extract('//text()') order by line).GetClobVal(),',')) as Procedure_Code
FROM
ProcedureDetails ProcTag
INNER JOIN dba_source codeline ON ProcTag.packagename=codeline.name
AND ProcTag.schemaname=codeline.owner
and ProcTag.typename=codeline.type
and codeline.line between ProcTag.startline and ProcTag.endline
--WHERE PROCEDURE_NAME='PROCEDURE TRANS_KAT_INSO'
group by
ProcTag.packagename ,
ProcTag.schemaname,
ProcTag.typename,
ProcTag.PROCEDURE_NAME,
ProcTag.startline,
ProcTag.endline
)
-- extract all the reference code for the given table selected with it complete procedure code.
SELECT
ProcHeader.Packagename, ProcHeader.schemaname, ProcHeader.typename, ProcHeader.procedure_name, ProcHeader.Procedure_Code ,ProcHeader.startline,ProcHeader.endline,ProcReference.Tablename, ProcReference.opr
FROM
ProcCode ProcHeader
INNER JOIN
(
SELECT DISTINCT ProcCode.Packagename, ProcCode.schemaname, ProcCode.typename, ProcCode.procedure_name , TableDep.Tablename, TableDep.opr
FROM ProcCode
INNER JOIN TableDep ON ProcCode.packagename=TableDep.packagename
AND ProcCode.schemaname=TableDep.schemaname
and ProcCode.typename=TableDep.typename
and TableDep.refline between ProcCode.startline and ProcCode.endline
) ProcReference
ON ProcHeader.Packagename=ProcReference.Packagename
AND ProcHeader.schemaname=ProcReference.schemaname
AND ProcHeader.typename=ProcReference.typename
AND ProcHeader.procedure_name=ProcReference.procedure_name
;
这个问题已经有一个接受的答案,但无论如何在query
接受的答案中使用的将选择所有user sources
使用特定表的。
因为问题是特定的,所以Procedures
您可以进行以下查询以获取结果
SELECT * FROM user_source WHERE text LIKE '%YourTableName%' and TYPE='PROCEDURE';