【问题标题】:Finding sequences and triggers associated with an Oracle table查找与 Oracle 表关联的序列和触发器
【发布时间】:2021-02-11 00:46:05
【问题描述】:

我已使用此查询来获取属于 Oracle 数据库用户的序列列表:

SELECT * FROM all_sequences x,all_tables B
WHERE x.sequence_owner=B.owner AND B.TABLE_NAME='my_table';

但是那个数据库用户也有更多的序列,所以查询返回我数据库用户的所有序列。任何人都可以帮助我使用查询找到my_table 的特定序列,以便我可以在我的应用程序中获取自动增量ID。

【问题讨论】:

  • 序列不直接链接到表,只能通过触发器或显式插入语句(可能在存储过程/包中)间接链接。既然您提到“自动增量”,大概您正在寻找一个设置值的触发器;但是你不需要知道它,ID会在后台自动设置。除非您有将序列名称与表名称相关联的命名约定,否则您需要搜索触发代码(在 all_source 中),如果它对您可见,并计算出表格形式 - 更容易询问另一个用户,也许吧?
  • 实际上,我想要获取我的数据库用户的表列表的查询以及表中使用的序列和触发器。
  • @user2492525,没有办法查询哪些序列用于任何表,因为 Oracle 不维护它们之间的连接。您的应用程序可能使用触发器来填充 id,在这种情况下,Alex Poole 的回答可能有用;或者另一个应用程序可能根本不使用触发器并在应用程序代码中调用序列。底线是,您的问题没有通用的解决方案。

标签: oracle


【解决方案1】:

我想要获取我的数据库用户的表列表的查询以及表中使用的序列和触发器

您可以从user_triggers 视图中获取与您的表关联的触发器。然后,您可以在 user_dependencies 中查找为这些触发器记录的任何依赖项,其中可能包括序列以外的对象(包等),因此将这些依赖项加入 user_sequences 视图只会显示您感兴趣的那些。

类似这样,假设您正在查看自己的架构,并且您只对引用序列的触发器感兴趣(不一定会执行“自动递增”,但很可能会这样做):

select tabs.table_name,
  trigs.trigger_name,
  seqs.sequence_name
from user_tables tabs
join user_triggers trigs
  on trigs.table_name = tabs.table_name
join user_dependencies deps
  on deps.name = trigs.trigger_name
join user_sequences seqs
  on seqs.sequence_name = deps.referenced_name;

SQL Fiddle demo.

如果您实际上正在查看不同的架构,那么您需要使用all_tables 等,并为您正在寻找的用户过滤并加入所有者列。如果你想包含没有触发器的表,或者不引用序列的触发器,你可以使用外连接。


寻找不同架构的版本,尽管这假设您具有访问数据字典信息所需的权限 - 表等对您可见,但它们可能不可见:

select tabs.table_name,
  trigs.trigger_name,
  seqs.sequence_name
from all_tables tabs
join all_triggers trigs
  on trigs.table_owner = tabs.owner
  and trigs.table_name = tabs.table_name
join all_dependencies deps
  on deps.owner = trigs.owner
  and deps.name = trigs.trigger_name
join all_sequences seqs
  on seqs.sequence_owner = deps.referenced_owner
  and seqs.sequence_name = deps.referenced_name
where tabs.owner = '<owner>';

如果看不到它们,那么您可能需要查看 DBA 视图,如果您有足够的权限:

select tabs.table_name,
  trigs.trigger_name,
  seqs.sequence_name
from dba_tables tabs
join dba_triggers trigs
  on trigs.table_owner = tabs.owner
  and trigs.table_name = tabs.table_name
join dba_dependencies deps
  on deps.owner = trigs.owner
  and deps.name = trigs.trigger_name
join dba_sequences seqs
  on seqs.sequence_owner = deps.referenced_owner
  and seqs.sequence_name = deps.referenced_name
where tabs.owner = '<owner>';

【讨论】:

  • @user2492525 - 那你为什么要这么做?为什么不在连接中包含表/触发器/序列名称?
  • 我刚刚加入了这一切,但我的序列名称与我的触发器名称不同,因此它不会返回任何值
  • @user2492525 - 我不知道为什么这是个问题,我链接到的 SQL Fiddle 有不同的名称。您只需要在每个阶段加入适当的名称即可。
  • 我自己通过使用触发器主体解决了这个问题,它具有序列名称。使用编程我拆分序列名称并得到它。感谢大家帮助我尽快完成工作。跨度>
【解决方案2】:

一种方法是运行这些查询以检查您的functionsprocedurespackagesTriggers 中是否使用了任何sequence 的伪列(NEXTVALCURRVAL)或PL/SQL JAVA SOURCE

select * from user_source where 
         UPPER(TEXT) LIKE '%NEXTVAL%';   

select * from all_source where 
         UPPER(TEXT) LIKE '%NEXTVAL%';  

然后转到特定的Procedure, Function or Trigger 以检查哪个列/表被序列填充。 该查询也可以与'%CURRVAL%'一起使用

如果您从 JDBC 或其他使用 sequence 的外部应用程序运行插入,这可能无济于事。


Oracle 12c 引入了IDENTITY 列,您可以使用它创建一个带有标识列的表,该标识列是默认生成的。

CREATE TABLE t1 (c1 NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY, 
                   c2 VARCHAR2(10));

这将在内部创建一个sequence,它会自动为表的列生成值。所以,如果您想知道哪个序列为哪个表生成值,您可以查询all_tab_columns

SELECT data_default AS sequence_val
    ,table_name
    ,column_name
FROM all_tab_columns
WHERE OWNER = 'HR'
    AND identity_column = 'YES';

SEQUENCE_VAL                             |TABLE_NAME               |COLUMN_NAME
-----------------------------------------|-------------------------------------
"HR"."ISEQ$$_78160".nextval              |T1                       |C1

【讨论】:

    【解决方案3】:

    我找到了解决这个问题的方法来猜测特定序列的序列

    select * from SYS.ALL_SEQUENCES where SEQUENCE_OWNER='OWNER_NAME' and LAST_NUMBER between (select max(FIELD_NAME) from TABLE_NAME) and (select max(FIELD_NAME)+40 from TABLE_NAME);
    

    此查询将通过使用序列搜索字段的 MAX 值与最大值 + 40 之间的序列值的 LAST_NUMBER 来猜测(在我的情况下缓存值为 20,所以我输入 40)

    【讨论】:

      【解决方案4】:

      从 sys.ALL_TAB_IDENTITY_COLS 中选择 SEQUENCE_NAME,其中所有者 = 'SCHEMA_NAME' 和 table_name = 'TABLE_NAME';

      【讨论】:

      • 点评来源: Stack Overflow 上不鼓励仅使用代码的答案,因为它们没有解释它是如何解决问题的。请编辑您的答案以解释此代码的作用以及它如何回答问题,以便它对 OP 以及其他有类似问题的用户有用。请参阅:How do I write a good answer?。谢谢
      • 这也仅适用于标识列,不适用于其他序列,尤其不适用于序列+触发器组合 - 无论如何,在过去,表格和序列之间的“墨水”。问题是在 Oracle 12c 发布之前,所以身份列还不存在。
      猜你喜欢
      • 1970-01-01
      • 2014-05-05
      • 1970-01-01
      • 2015-03-04
      • 2012-11-05
      • 2014-10-28
      • 2017-07-28
      • 1970-01-01
      • 2013-09-30
      相关资源
      最近更新 更多