쿼리를 저장하는 열에서 SQL을 사용하여 테이블 이름 추출

Dec 09 2020

테이블에 쿼리가 저장되고 해당 쿼리에서 테이블 이름을 추출해야합니다.

표 : 메인

신분증 쿼리 텍스트
1 a.record_id, a.name, b.person FROM database.atable a join database.btable b on b.id = a.id;
2 c.record_id, c.name, d.person FROM database.ctable c join database.dtable d on c.id = d.id를 선택합니다.

예상 결과 :

database.atable
database.ctable

SELECT SUBSTR(querytext, position('database.' in querytext), 30) FROM main;

이것은 거의 작동하지만 테이블 이름이 얼마나 길거나 짧을 수 있는지 모르겠습니다. 30보다 길면 결과가 잘립니다. 더 짧으면 쿼리의 다른 부분을 포함 할 수 있습니다. 나는 strtok을 읽고 그 이름을 멈출 때 그 공간에 도달하기 위해 그것을 사용하는 것에 대해 생각했지만 제대로 작동하지 못했습니다.

답변

2 esqew Dec 09 2020 at 02:18

다음과 같은 좋은 사용 사례가 될 수 있습니다 REGEXP_SUBSTR.

SELECT REGEXP_SUBSTR(querytext, '(<?FROM database\.)(.+?\b)', 1, 1, 'i')

패턴은 패턴과 FROM database.일치하는 테이블 이름 바로 앞에 오는 문자열 리터럴 을 찾습니다 (.+?\b).

또한-패턴 은 샘플 데이터로 판단되는 단어 경계 문자 ( ) 까지 적어도 한 번 발생하는 (.+?\b)모든 문자 ( .) 와 일치합니다 ( +) 비 탐욕적 ( ?토큰) \b, 테이블 이름 바로 앞의 공백에서 일치해야합니다.

Regex101 과 같은 유틸리티를 사용하여이 패턴이 어떻게 해석되는지 더 자세히 볼 수 있습니다 .


Teradata의 PCRE 스타일 RegExp 지원에 관한 추가 (약간 접선이지만) 읽기 : teradata의 Regex 구문

access_granted Dec 09 2020 at 02:49

약간 펑키 해 보이지만 작동해야합니다.

select 
  strtok( substr( strsql, index(strsql,'FROM ')+length('FROM '), length(strsql)), ' ', 1 ) 
from (
select 
'select c.record_id, c.name, d.person FROM database.ctable c join database.dtable d on c.id= d.id' 
  as strsql
) s1;

또는 귀하의 경우

select strtok( 
  substr( querytext, index(querytext,'FROM ')+length('FROM '), length(querytext)) 
  ,' ', 1 
  ) from main;