source

Oracle의 열에 시퀀스가 있는지 확인합니다.

manycodes 2023. 6. 15. 21:59
반응형

Oracle의 열에 시퀀스가 있는지 확인합니다.

오라클의 열이 시퀀스에서 채워지는지 확인하려고 합니다.Oracle이 시퀀스를 처리하는 방식에 대해 제가 느낀 점은 시퀀스와 열이 별도의 엔티티이므로 다음과 같은 다음 시퀀스 값을 수동으로 삽입해야 한다는 것입니다.

insert into tbl1 values(someseq.nextval, 'test')

테이블 트리거에 넣거나 합니다.시퀀스에서 열이 채워졌는지 여부를 확인하는 것이 중요하지 않음을 의미합니다.그것이 맞습니까?시퀀스에서 열이 채워지는지 확인하는 방법에 대한 아이디어가 있습니까?

맞습니다. 시퀀스는 테이블과 별개이며 단일 시퀀스를 사용하여 모든 테이블을 채울 수 있으며 일부 테이블의 열에 있는 값은 수동으로 생성된 값을 제외하고 대부분 시퀀스(또는 시퀀스 집합)에서 나올 수 있습니다.

즉, 열과 시퀀스 사이에는 필수적인 연결이 없으므로 스키마에서 이러한 관계를 검색할 수 있는 방법이 없습니다.

궁극적으로 분석은 테이블에 데이터를 삽입하거나 업데이트하는 모든 응용 프로그램의 소스 코드에 대한 것입니다.다른 건 보장되지 않습니다.테이블을 수정할 수 있는 유일한 방법인 저장 프로시저가 있거나 값을 설정하는 트리거가 있는 경우 또는 기타와 같은 경우 검색 범위를 줄일 수 있습니다.그러나 일반적인 해결책은 '원천 분석'이라는 '비해'입니다.

시퀀스가 트리거에 사용되는 경우 채워지는 테이블을 찾을 수 있습니다.

SQL> select t.table_name, d.referenced_name as sequence_name
  2  from   user_triggers t
  3         join user_dependencies d
  4         on d.name = t.trigger_name
  5  where  d.referenced_type = 'SEQUENCE'
  6  and    d.type = 'TRIGGER'
  7  /

TABLE_NAME                     SEQUENCE_NAME
------------------------------ ------------------------------
EMP                            EMPNO_SEQ

SQL>

이 쿼리를 변경하여 시퀀스를 사용하는 저장 프로시저 등을 찾을 수 있습니다.

Oracle 시퀀스와 데이터베이스의 사용 간에는 직접적인 메타데이터 링크가 없습니다.USER_SECENCES 메타데이터를 쿼리하고 LAST_NUMBER 열을 열의 데이터와 비교하여 열의 값이 시퀀스와 관련되어 있는지 여부를 지능적으로 추측할 수 있습니다.

select t.table_name,
   d.referenced_name  as sequence_name,
   d.REFERENCED_OWNER as "OWNER",
   c.COLUMN_NAME
  from user_trigger_cols t, user_dependencies d, user_tab_cols c
 where d.name = t.trigger_name
   and t.TABLE_NAME = c.TABLE_NAME
   and t.COLUMN_NAME = c.COLUMN_NAME
   and d.referenced_type = 'SEQUENCE'
   and d.type = 'TRIGGER'

Jonathan이 지적했듯이, 두 물체를 연관시킬 수 있는 직접적인 방법은 없습니다.그러나 기본 키 및 시퀀스/트리거에 대해 "표준을 유지"하는 경우 기본 키를 찾은 다음 제약 조건을 테이블 시퀀스에 연결하여 확인할 수 있습니다.

Multi-db 제품을 만들고 있기 때문에 유사한 것이 필요했고 의 DataTable 개체에 있는 속성으로 일부 클래스를 복제하려고 했습니다.시퀀스에서만 찾을 수 있는 자동 증분, IncrementSeed 및 IncrementStep이 있는 네트.

따라서 테이블에 대해 PK를 사용하고 항상 테이블에 삽입할 트리거와 연결된 시퀀스를 사용하면 이 작업이 유용할 수 있습니다.

select tc.table_name,
  case tc.nullable 
    when 'Y' then 1
    else 0
  end as is_nullable,
  case ac.constraint_type 
    when 'P' then 1
    else 0
  end as is_identity,
  ac.constraint_type,
  seq.increment_by as auto_increment_seed,
  seq.min_value as auto_increment_step,
  com.comments as caption,
  tc.column_name,
  tc.data_type,
  tc.data_default as default_value,
  tc.data_length as max_length,
  tc.column_id,
  tc.data_precision as precision,
  tc.data_scale as scale
from SYS.all_tab_columns tc
left outer join SYS.all_col_comments com
  on (tc.column_name = com.column_name and tc.table_name = com.table_name)
LEFT OUTER JOIN  SYS.ALL_CONS_COLUMNS CC 
  on (tc.table_name = cc.table_name and tc.column_name = cc.column_name and tc.owner = cc.owner)
LEFT OUTER JOIN SYS.ALL_CONSTRAINTS AC
  ON (ac.constraint_name = cc.constraint_name and ac.owner = cc.owner)
LEFT outer join user_triggers trg
  on (ac.table_name = trg.table_name and ac.owner = trg.table_owner)
LEFT outer join user_dependencies dep
  on (trg.trigger_name = dep.name and dep.referenced_type='SEQUENCE' and dep.type='TRIGGER')
LEFT outer join user_sequences seq
  on (seq.sequence_name = dep.referenced_name)  
where tc.table_name = 'TABLE_NAME'
and tc.owner = 'SCHEMA_NAME'
AND AC.CONSTRAINT_TYPE = 'P'
union all
select tc.table_name,
  case tc.nullable 
    when 'Y' then 1
    else 0
  end as is_nullable,
  case ac.constraint_type 
    when 'P' then 1
    else 0
  end as is_identity,
  ac.constraint_type,
  seq.increment_by as auto_increment_seed,
  seq.min_value as auto_increment_step,
  com.comments as caption,
  tc.column_name,
  tc.data_type,
  tc.data_default as default_value,
  tc.data_length as max_length,
  tc.column_id,
  tc.data_precision as precision,
  tc.data_scale as scale
from SYS.all_tab_columns tc
left outer join SYS.all_col_comments com
  on (tc.column_name = com.column_name and tc.table_name = com.table_name)
LEFT OUTER JOIN  SYS.ALL_CONS_COLUMNS CC 
  on (tc.table_name = cc.table_name and tc.column_name = cc.column_name and tc.owner = cc.owner)
LEFT OUTER JOIN SYS.ALL_CONSTRAINTS AC
  ON (ac.constraint_name = cc.constraint_name and ac.owner = cc.owner)
LEFT outer join user_triggers trg
  on (ac.table_name = trg.table_name and ac.owner = trg.table_owner)
LEFT outer join user_dependencies dep
  on (trg.trigger_name = dep.name and dep.referenced_type='SEQUENCE' and dep.type='TRIGGER')
LEFT outer join user_sequences seq
  on (seq.sequence_name = dep.referenced_name)  
where tc.table_name = 'TABLE_NAME'
and tc.owner = 'SCHEMA_NAME'
AND AC.CONSTRAINT_TYPE is null;

그러면 스키마/테이블의 열 목록이 다음과 같이 표시됩니다.

  • 테이블명
  • 열이 null일 경우
  • 제약 조건 유형(PK에만 해당)
  • 시드 증분(시퀀스에서)
  • 증분 단계(시퀀스에서)
  • 열 주석
  • 칼럼 이름은 물론입니다 :)
  • 자료형
  • 기본값(있는 경우)
  • 컬럼 길이
  • 인덱스(열 ID)
  • 정밀도(숫자의 경우)
  • 척도(숫자의 경우)

코드를 최적화할 수 있다고 확신하지만, 이 코드를 사용하여 테이블의 "메타데이터 로드"를 수행한 후 프론트엔드에서 메타데이터를 엔티티로 표시합니다.

기본 키만 필터링하고 복합 키 제약 조건은 신경 쓰지 않으므로 검색하지 않습니다.만약 당신이 그렇게 한다면, 당신은 코드를 수정해야 할 것이고, 당신은 한 열을 두 번 얻을 수 있기 때문에 중복을 필터링해야 할 것입니다. (하나는 PK 제약 조건, 다른 하나는 복합 키).

언급URL : https://stackoverflow.com/questions/1730043/find-if-a-column-in-oracle-has-a-sequence

반응형