我有一个11G的数据库。我需要检查一些存储过程,看看它们是否使用特定的表。 (前端和后端sps)我可以完全访问数据库,并且还有一个存储在TFS上的项目所有单个sp的副本。
我想要一种方法来生成与此特定表交互的所有sp的列表。我不熟悉如何寻找这些。任何人都可以建议获得这些数据的最合理方式吗?
感谢。
答案 0 :(得分:14)
如果我理解正确,那么您正试图在所有存储过程中搜索table
的出现位置。在这种情况下,您可以使用此查询:
搜索架构中SP
的出现次数
SELECT * FROM user_source WHERE text LIKE '%tab_name%';
在所有模式中搜索SP
的出现次数
SELECT * FROM all_source WHERE text LIKE '%tab_name%';
答案 1 :(得分:5)
两件事,在PL / SQL中有一些变化需要重新编译pl / sql对象,其他则不需要。
要查看第一个,您可以看到ALL_DEPENDENCIES
视图。或DBA_,如果您愿意。
如果您只想查看表名在所有pl / sql代码中的显示位置,那么对表的更改是否需要重新编译,您可以使用ALL_SOURCE
使用upper和%,但是可能需要一些时间。
答案 2 :(得分:3)
我使用PLSQL Developer,您可以浏览到表(或其他对象),并查看'Referenced by',以查看引用该表的所有对象。这就像它变得一样简单。 我可以想象其他工具具有类似的功能。
我不知道这个预先解析的信息是否可以在Oracle中获得,但我可以这么想,因为这些工具似乎工作得非常快。
此信息可在All_DEPENDENCIES
视图中找到,这些工具可能会使用这些信息。
存储过程的源可以在USER_SOURCE
(或ALL_SOURCE
)视图中找到,其中存储了整个数据库的结构。然而,从那里获取和解析代码会非常麻烦。
答案 3 :(得分:0)
以下是我为给定的@schema(仅限大写)和@table(仅限大写)执行影响分析(仅限MERGE,INSERT和UPDATE)的片段。它将返回所有过程名称,过程代码,行号和行号以及其他详细信息。它可以很容易地用于包括函数对象而不是包。我正在开发一个可以跨所有架构或选定架构运行的实用程序(也包括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
;
答案 4 :(得分:0)
此问题已经有一个可接受的答案,但是无论如何,在接受的答案中使用的query
将选择所有使用特定表的user sources
。
由于问题是关于Procedures
的特定问题,您可以通过以下查询获取结果
SELECT * FROM user_source WHERE text LIKE '%YourTableName%' and TYPE='PROCEDURE';