[SQL] 정규 표현식은 쿼리의 모든 테이블 이름을 찾을 수
SQL정규 표현식은 쿼리의 모든 테이블 이름을 찾을 수
나는 정규 표현식에서 그 뜨거운 아니다 그것은 내 작은 마음이 어떤 것을 녹아했다.
나는 쿼리의 모든 테이블 이름을 찾기 위해 노력하고있다. 그래서 쿼리가 있다고 가정 :
SELECT one, two, three FROM table1, table2 WHERE X=Y
나는 "표 1, 표 2"또는 "표"와 "표 2"뽑아 싶습니다
그러나 어떤 경우 문 어떤 존재하지 않는 경우. 파일의 마지막이 될 수도 있고, 나는 시간의 "대부분"이 문제가되지 않을 것입니다 알고에 의해 그룹 또는 등으로 주문이있을 수 있지만 "대부분의"코딩의 아이디어를 좋아하지 않는다 상황과 나는 일이 잘못 이상을 이동시킬 수있는 구멍을 떠난 알고.
이것은 행할 정규식 표현인가? 나는 정규식 pleb되는 건가요?
(추신 :이 C #에서 수행하지만 훨씬 중요하지 않습니다 가정한다).
해결법
-
==============================
1.그것이 나타나는 것보다 훨씬 더 복잡로 정규식이 매우 좋지 않다 :
그것이 나타나는 것보다 훨씬 더 복잡로 정규식이 매우 좋지 않다 :
나는에 갈 수 있었다.
당신이 할 수있는 것은 SQL 파서 모양이며, 그 통해 쿼리를 실행합니다.
-
==============================
2.모든 것은 SQL 컨텍스트에서 이러한 정규식의 유용성에 대해 말했다. (수단에는 서브 쿼리는,, 등 조인 있음), 당신이 사용하지 수는 정규식 주장하고 SQL 문은 항상 당신이 보여처럼 보면
모든 것은 SQL 컨텍스트에서 이러한 정규식의 유용성에 대해 말했다. (수단에는 서브 쿼리는,, 등 조인 있음), 당신이 사용하지 수는 정규식 주장하고 SQL 문은 항상 당신이 보여처럼 보면
FROM\s+([^ ,]+)(?:\s*,\s*([^ ,]+))*\s+
-
==============================
3.나는 꽤 늦게 나는 나는 현재 우리의 모든 데이터베이스 개체를 분석하기 위해 사용하고 정규식을 공유 할 것이라고 생각하지만 파티에 그리고 난 그것을 사용하여이 일을 할 수없는 그 감정에 동의하지 않는다.
나는 꽤 늦게 나는 나는 현재 우리의 모든 데이터베이스 개체를 분석하기 위해 사용하고 정규식을 공유 할 것이라고 생각하지만 파티에 그리고 난 그것을 사용하여이 일을 할 수없는 그 감정에 동의하지 않는다.
정규식은 몇 가지 가정이있다
당신이 (가)를 사용하지 않는 1), B 구문 스타일에 가입
2) 무엇이든 정규식 파서 당신이 지원하는 경우를 무시하고 사용하고 있습니다.
3)있는 거 분석, 선택, 조인, 업데이트, 삭제 및 자릅니다. 우리가 그들을 사용하지 않기 때문에 그것은 상기 병합을 지원하지 않습니다 / 자연, 그러나 나는 추가 지원이 추가 어렵지 않을 것이라고 확신합니다.
나는 테이블 내가 말해 명명 된 캡처 그룹을 포함했다, 그래서의 일부입니다 어떤 거래의 유형을 알고 싶어하고있다.
오랫동안 지금은 사용하지 않는 한 정규식 그래서 아마 지금까지 모든이를 테스트하는 것이 정확한 내 그러나 할 수있는 개선이 있습니다.
\bjoin\s+(?<Retrieve>[a-zA-Z\._\d]+)\b|\bfrom\s+(?<Retrieve>[a-zA-Z\._\d]+)\b|\bupdate\s+(?<Update>[a-zA-Z\._\d]+)\b|\binsert\s+(?:\binto\b)?\s+(?<Insert>[a-zA-Z\._\d]+)\b|\btruncate\s+table\s+(?<Delete>[a-zA-Z\._\d]+)\b|\bdelete\s+(?:\bfrom\b)?\s+(?<Delete>[a-zA-Z\._\d]+)\b
-
==============================
4.나는 훌륭한 파서가이 사이트를 발견!
나는 훌륭한 파서가이 사이트를 발견!
http://www.sqlparser.com/
잘 가치. 치료를 작동합니다.
-
==============================
5.한 가지 해결 방법은 테이블과 뷰에 대한 명명 규칙을 구현하는 것입니다. 그런 다음 SQL 문은 이름 접두사에 구문 분석 할 수 있습니다.
한 가지 해결 방법은 테이블과 뷰에 대한 명명 규칙을 구현하는 것입니다. 그런 다음 SQL 문은 이름 접두사에 구문 분석 할 수 있습니다.
예를 들면 :
SELECT tbltable1.one, tbltable1.two, tbltable2.three FROM tbltable1 INNER JOIN tbltable2 ON tbltable1.one = tbltable2.three
배열에 분할 공백 :
( "선택" "tbltable1.one", "tbltable1.two", "tbltable1", "INNER가", "가입", "tbltable2" "FROM", "tbltable2.three", "ON", " tbltable1.one ","= ","tbltable2.three ")
기간 요소의 왼쪽하기 :
( "INNER가", "가입", "tbltable1"를 "tbltable1", "tbltable1", "tbltable2"을 "선택" "FROM", "tbltable2", "ON", "tbltable1", "=", " tbltable2 ")
기호 요소를 제거합니다 :
( "INNER"는 "tbltable2", "ON", "tbltable1", "tbltable2"를 "가입", "tbltable1"를 "tbltable1", "tbltable1", "tbltable2"을 "선택" "FROM")
고유 한 값으로 줄입니다 :
( "tbltable1", "tbltable2"을 "선택" "FROM", "INNER가", "가입", "ON")
왼쪽 3 자에 필터 = "TBL"
( "tbltable1", "tbltable2")
-
==============================
6.그것은 쉬운 확실히 아니다.
그것은 쉬운 확실히 아니다.
하위 쿼리를 생각해 보자.
select * from A join ( select top 5 * from B) on B.ID = A.ID where A.ID in ( select ID from C where C.DOB = A.DOB)
이 쿼리에 사용되는 세 개의 테이블이 있습니다.
-
==============================
7.나는 문자열을 토큰 화 및 테이블 이름을 결합 할 수 SQL 키워드를 찾을 쉬울 것 같아요. 당신은 이름이 FROM 따를 알고 있지만, 그들은 다음에 할 수 WHERE, GROUP BY, 그들은 쿼리의 끝에 있다면 모두에서 HAVING, 또는 전혀 키워드.
나는 문자열을 토큰 화 및 테이블 이름을 결합 할 수 SQL 키워드를 찾을 쉬울 것 같아요. 당신은 이름이 FROM 따를 알고 있지만, 그들은 다음에 할 수 WHERE, GROUP BY, 그들은 쿼리의 끝에 있다면 모두에서 HAVING, 또는 전혀 키워드.
-
==============================
8.건설 정규 표현식은 문제의 이상을 될 것입니다. 이 코드 지원에 기대 SQL의 맛에 따라, 방법의 수는 당신은 SQL 문에서 테이블이 비틀 거리고 참조 할 수 있습니다.
건설 정규 표현식은 문제의 이상을 될 것입니다. 이 코드 지원에 기대 SQL의 맛에 따라, 방법의 수는 당신은 SQL 문에서 테이블이 비틀 거리고 참조 할 수 있습니다.
조회가보기 또는 UDF에 대한 참조를 포함하는 경우 PLUS는 정보가 무엇인지에 대해 기본 테이블도 모두가 그것을 분석하여 그 정보를 얻을 완전히 실용적이지에서 문자열에되지 않습니다. 또한, 임시 테이블을 검색하고 결과에서 제외에 대해 현명하게 필요 했어.
이 작업을 수행해야하는 경우, 더 좋은 방법은 SQL을위한 것을 특정 데이터베이스 엔진에 API를 사용할 수 있도록하는 것입니다. 예를 들어, 당신은 쿼리를 기반으로 뷰를 만들고 그 뷰에 대한 종속성을 검출하기 위해 DB 서버 API를 사용할 수 있습니다. 혹시 엄청난 노력없이 쿼리 엔진 리버스 엔지니어링하는 것보다 DB 엔진은 훨씬 더 안정적으로 구문 분석 할 수있을 것입니다.
찾기 종속성 SQL 2005 서버 : 당신은 SQL Server와 함께 작업하고, 우연히 여기에 해당 플랫폼에 대한 의존성을 검출에 대한 기사 인 경우
-
==============================
9.이것은 INSERT INTO 쿼리에 테이블 이름을 가져옵니다 :
이것은 INSERT INTO 쿼리에 테이블 이름을 가져옵니다 :
(?<=(INTO)\s)[^\s]*(?=\(())
다음은 동일하지만, 조인을 포함하는 선택으로 할 것
(?<=(from|join)\s)[^\s]*(?=\s(on|join|where))
다음과 같은 정규식을 사용하여 쿼리를 삽입에서 개최되는 단지 값을 반환하려는 경우 마지막으로 삽입에 다시가는
(?i)(?<=VALUES[ ]*\().*(?=\))
나는이 오래된 스레드 알고 있지만 다른 사람이 둘러보고 도움이 될 수
즐겨
-
==============================
10.나는 모두에게 위의 시도하지만 쿼리의 다양한 사용하기 때문에 아무도 일하지. 나는 SQL_Parser라는 PEAR 라이브러리를 사용하지만 PHP 작업,하지만 내 솔루션이 도움이되기를 바랍니다 있어요. 또한, 나는 아포스트로피에 문제가 있었고, 난 그것을 구문 분석하기 전에 쿼리의 모든 필드 섹션을 제거하기로 결정 그래서 MySQL은 sencences을 보유.
나는 모두에게 위의 시도하지만 쿼리의 다양한 사용하기 때문에 아무도 일하지. 나는 SQL_Parser라는 PEAR 라이브러리를 사용하지만 PHP 작업,하지만 내 솔루션이 도움이되기를 바랍니다 있어요. 또한, 나는 아포스트로피에 문제가 있었고, 난 그것을 구문 분석하기 전에 쿼리의 모든 필드 섹션을 제거하기로 결정 그래서 MySQL은 sencences을 보유.
function getQueryTable ($query) { require_once "SQL/Parser.php"; $parser = new SQL_Parser(); $parser->setDialect('MySQL'); // Stripping fields section $queryType = substr(strtoupper($query),0,6); if($queryType == 'SELECT') { $query = "SELECT * ".stristr($query, "FROM"); } if ($havingPos = stripos($query, 'HAVING')) { $query = substr($query, 0, $havingPos); } $struct = $parser->parse($query); $tableReferences = $struct[0]['from']['table_references']['table_factors']; foreach ((Array) $tableReferences as $ref) { $tables[] = ($ref['database'] ? $ref['database'].'.' : $ref['database']).$ref['table']; } return $tables; }
-
==============================
11.PHP에서,이 기능은, 그것은 SQL 문에 사용 된 테이블 이름을 가진 배열을 반환 사용
PHP에서,이 기능은, 그것은 SQL 문에 사용 된 테이블 이름을 가진 배열을 반환 사용
function sql_query_get_tables($statement){ preg_match_all("/(from|into|update|join) [\\'\\´]?([a-zA-Z0-9_-]+)[\\'\\´]?/i", $statement, $matches); if(!empty($matches)){ return array_unique($matches[2]); }else return array(); }
그것이 작동하지 않는 것을주의, b를 또는은 schema.tablename의 이름을 조인
나는 당신을 위해 일하는 희망
-
==============================
12.나는 선택과 추출 테이블 이름을 구문 분석 엑셀 매크로로이 코드를 사용했다.
나는 선택과 추출 테이블 이름을 구문 분석 엑셀 매크로로이 코드를 사용했다.
내 구문 분석 구문 A, B에서 선택하는 것이 가정, C는 사용되지 않습니다.
그냥 SQL 쿼리에 대해 실행하고 결과에 만족하지 않는 경우 당신은 멀리 예상 결과에서 코드 몇 줄 수 있어야합니다. 그냥 디버깅하고 그에 따라 코드를 수정합니다.
Sub get_tables() sql_query = Cells(5, 1).Value tables = "" 'get all tables after from sql_from = sql_query While InStr(1, UCase(sql_from), UCase("from")) > 0 i = InStr(1, UCase(sql_from), UCase("from")) sql_from = Mid(sql_from, i + 5, Len(sql_from) - i - 5) i = InStr(1, UCase(sql_from), UCase(" ")) While i = 1 sql_from = Mid(sql_from, 2, Len(sql_from) - 1) i = InStr(1, UCase(sql_from), UCase(" ")) end i = InStr(1, sql_join, Chr(9)) While i = 1 sql_join = Mid(sql_join, 2, Len(sql_join) - 1) i = InStr(1, sql_join, Chr(9)) end a = InStr(1, UCase(sql_from), UCase(" ")) b = InStr(1, sql_from, Chr(10)) c = InStr(1, sql_from, Chr(13)) d = InStr(1, sql_from, Chr(9)) MinC = a If MinC > b And b > 0 Then MinC = b If MinC > c And c > 0 Then MinC = c If MinC > d And d > 0 Then MinC = d tables = tables + "[" + Mid(sql_from, 1, MinC - 1) + "]" end 'get all tables after join sql_join = sql_query While InStr(1, UCase(sql_join), UCase("join")) > 0 i = InStr(1, UCase(sql_join), UCase("join")) sql_join = Mid(sql_join, i + 5, Len(sql_join) - i - 5) i = InStr(1, UCase(sql_join), UCase(" ")) While i = 1 sql_join = Mid(sql_join, 2, Len(sql_join) - 1) i = InStr(1, UCase(sql_join), UCase(" ")) end i = InStr(1, sql_join, Chr(9)) While i = 1 sql_join = Mid(sql_join, 2, Len(sql_join) - 1) i = InStr(1, sql_join, Chr(9)) end a = InStr(1, UCase(sql_join), UCase(" ")) b = InStr(1, sql_join, Chr(10)) c = InStr(1, sql_join, Chr(13)) d = InStr(1, sql_join, Chr(9)) MinC = a If MinC > b And b > 0 Then MinC = b If MinC > c And c > 0 Then MinC = c If MinC > d And d > 0 Then MinC = d tables = tables + "[" + Mid(sql_join, 1, MinC - 1) + "]" end tables = Replace(tables, ")", "") tables = Replace(tables, "(", "") tables = Replace(tables, " ", "") tables = Replace(tables, Chr(10), "") tables = Replace(tables, Chr(13), "") tables = Replace(tables, Chr(9), "") tables = Replace(tables, "[]", "") End Sub
from https://stackoverflow.com/questions/281041/regular-expression-to-find-all-table-names-in-a-query by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 여기서 () 절 성능 내부에 가입하고? (0) | 2020.06.15 |
---|---|
[SQL] 삽입 MySQL은 ROW_NUMBER () 등가 [중복] (0) | 2020.06.15 |
[SQL] 앱 엔진 자바 서블릿은 클라우드 SQL에 연결되지 않습니다 (0) | 2020.06.14 |
[SQL] PostgreSQL의 9.3을 사용하여 CTE UPSERT에 DEFAULT 값을 생성 (0) | 2020.06.14 |
[SQL] 그 조각하여 문자열의 조각 순서를 선택 MYSQL (0) | 2020.06.14 |