问题 查找与Oracle表关联的序列和触发器


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

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

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


7917
2018-06-17 08:09


起源

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


答案:


我想查询我的数据库用户的表的列表与表中使用的序列和触发器

您可以从中获取与表关联的触发器 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小提琴演示

如果您实际上正在查看不同的架构,那么您将需要使用 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>';

7
2018-06-17 09:12



@ user2492525 - 你为什么这样做?为什么不在连接中包含表/触发器/序列名称? - Alex Poole
我加入了所有这些,但我的序列名称与我的触发器名称不同,因此它不会返回任何值 - user2492525
@ user2492525 - 我不确定为什么这是一个问题,我链接的SQL Fiddle有不同的名字。您只需要在每个阶段加入适当的名称。 - Alex Poole
我通过使用触发器体来解决问题,并且具有序列名称。使用编程我拆分序列名称并得到它。谢谢大家帮助我尽快完成工作。 - user2492525


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

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);

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


3
2018-02-20 09:24





一种方法是运行这些查询以检查是否有任何查询 sequence'Pseudocolumns(NEXTVAL 和 CURRVAL 用于你的 functions , procedurespackagesTriggers 要么 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

2
2018-04-01 15:57