7

我有一个11G的数据库。我需要检查一些存储过程,看看它们是否使用特定的表。(前端和后端sps)我拥有对数据库的完全访问权限,并且我还拥有存储在TFS 上的项目的所有单个sps 的副本。

我想要一种方法来生成与这个特定表交互的所有 sps 的列表。我不熟悉如何去搜索这些。任何人都可以建议获取这些数据的最合乎逻辑的方式吗?

谢谢。

4

5 回答 5

19

如果我理解正确,您正在尝试table在所有存储的过程中搜索 a 的出现。在这种情况下,您可以使用以下查询:

SP在您的架构中搜索出现时

SELECT * FROM user_source WHERE text LIKE '%tab_name%';

SP在所有模式中搜索出现时

SELECT * FROM all_source WHERE text LIKE '%tab_name%';
于 2013-02-11T13:01:45.050 回答
5

有两件事,在 PL/SQL 中有一些更改需要重新编译 pl/sql 对象,其他则不需要。要看到第一个,您有ALL_DEPENDENCIES视图。或 DBA_,如果您愿意。

如果只是想查看表名在所有 pl/sql 代码中出现的位置,对表的更改是否需要重新编译,可以使用ALL_SOURCE大写字母和 %,但可能需要一些时间。

于 2013-02-11T13:05:32.593 回答
3

我使用 PLSQL Developer,您可以在其中浏览到表(或其他对象),并查看“引用者”,以查看引用该表的所有对象。这很容易。我可以想象其他工具也有类似的功能。

我不知道这个预先解析的信息是否在 Oracle 中很容易获得,但我可以想象,因为这些工具似乎工作得很快。

此信息在All_DEPENDENCIES这些工具可能使用的视图中可用。

存储过程的来源可以在USER_SOURCE(或ALL_SOURCE)视图中找到,其中存储了整个数据库的结构。然而,从那里获取和解析代码会非常麻烦。

于 2013-02-11T12:59:49.683 回答
1

这是我为给定的@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
;
于 2018-03-19T11:34:30.053 回答
0

这个问题已经有一个接受的答案,但无论如何在query接受的答案中使用的将选择所有user sources使用特定表的。

因为问题是特定的,所以Procedures您可以进行以下查询以获取结果

SELECT * FROM user_source WHERE text LIKE '%YourTableName%' and TYPE='PROCEDURE';
于 2018-10-17T11:56:32.250 回答