복붙노트

[SQL] 정규 표현식은 쿼리의 모든 테이블 이름을 찾을 수

SQL

정규 표현식은 쿼리의 모든 테이블 이름을 찾을 수

나는 정규 표현식에서 그 뜨거운 아니다 그것은 내 작은 마음이 어떤 것을 녹아했다.

나는 쿼리의 모든 테이블 이름을 찾기 위해 노력하고있다. 그래서 쿼리가 있다고 가정 :

SELECT one, two, three FROM table1, table2 WHERE X=Y

나는 "표 1, 표 2"또는 "표"와 "표 2"뽑아 싶습니다

그러나 어떤 경우 문 어떤 존재하지 않는 경우. 파일의 마지막이 될 수도 있고, 나는 시간의 "대부분"이 문제가되지 않을 것입니다 알고에 의해 그룹 또는 등으로 주문이있을 수 있지만 "대부분의"코딩의 아이디어를 좋아하지 않는다 상황과 나는 일이 잘못 이상을 이동시킬 수있는 구멍을 떠난 알고.

이것은 행할 정규식 표현인가? 나는 정규식 pleb되는 건가요?

(추신 :이 C #에서 수행하지만 훨씬 중요하지 않습니다 가정한다).

해결법

  1. ==============================

    1.그것이 나타나는 것보다 훨씬 더 복잡로 정규식이 매우 좋지 않다 :

    그것이 나타나는 것보다 훨씬 더 복잡로 정규식이 매우 좋지 않다 :

    나는에 갈 수 있었다.

    당신이 할 수있는 것은 SQL 파서 모양이며, 그 통해 쿼리를 실행합니다.

  2. ==============================

    2.모든 것은 SQL 컨텍스트에서 이러한 정규식의 유용성에 대해 말했다. (수단에는 서브 쿼리는,, 등 조인 있음), 당신이 사용하지 수는 정규식 주장하고 SQL 문은 항상 당신이 보여처럼 보면

    모든 것은 SQL 컨텍스트에서 이러한 정규식의 유용성에 대해 말했다. (수단에는 서브 쿼리는,, 등 조인 있음), 당신이 사용하지 수는 정규식 주장하고 SQL 문은 항상 당신이 보여처럼 보면

    FROM\s+([^ ,]+)(?:\s*,\s*([^ ,]+))*\s+ 
    
  3. ==============================

    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. ==============================

    4.나는 훌륭한 파서가이 사이트를 발견!

    나는 훌륭한 파서가이 사이트를 발견!

    http://www.sqlparser.com/

    잘 가치. 치료를 작동합니다.

  5. ==============================

    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. ==============================

    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. ==============================

    7.나는 문자열을 토큰 화 및 테이블 이름을 결합 할 수 SQL 키워드를 찾을 쉬울 것 같아요. 당신은 이름이 FROM 따를 알고 있지만, 그들은 다음에 할 수 WHERE, GROUP BY, 그들은 쿼리의 끝에 있다면 모두에서 HAVING, 또는 전혀 키워드.

    나는 문자열을 토큰 화 및 테이블 이름을 결합 할 수 SQL 키워드를 찾을 쉬울 것 같아요. 당신은 이름이 FROM 따를 알고 있지만, 그들은 다음에 할 수 WHERE, GROUP BY, 그들은 쿼리의 끝에 있다면 모두에서 HAVING, 또는 전혀 키워드.

  8. ==============================

    8.건설 정규 표현식은 문제의 이상을 될 것입니다. 이 코드 지원에 기대 SQL의 맛에 따라, 방법의 수는 당신은 SQL 문에서 테이블이 비틀 거리고 참조 할 수 있습니다.

    건설 정규 표현식은 문제의 이상을 될 것입니다. 이 코드 지원에 기대 SQL의 맛에 따라, 방법의 수는 당신은 SQL 문에서 테이블이 비틀 거리고 참조 할 수 있습니다.

    조회가보기 또는 UDF에 대한 참조를 포함하는 경우 PLUS는 정보가 무엇인지에 대해 기본 테이블도 모두가 그것을 분석하여 그 정보를 얻을 완전히 실용적이지에서 문자열에되지 않습니다. 또한, 임시 테이블을 검색하고 결과에서 제외에 대해 현명하게 필요 했어.

    이 작업을 수행해야하는 경우, 더 좋은 방법은 SQL을위한 것을 특정 데이터베이스 엔진에 API를 사용할 수 있도록하는 것입니다. 예를 들어, 당신은 쿼리를 기반으로 뷰를 만들고 그 뷰에 대한 종속성을 검출하기 위해 DB 서버 API를 사용할 수 있습니다. 혹시 엄청난 노력없이 쿼리 엔진 리버스 엔지니어링하는 것보다 DB 엔진은 훨씬 더 안정적으로 구문 분석 할 수있을 것입니다.

    찾기 종속성 SQL 2005 서버 : 당신은 SQL Server와 함께 작업하고, 우연히 여기에 해당 플랫폼에 대한 의존성을 검출에 대한 기사 인 경우

  9. ==============================

    9.이것은 INSERT INTO 쿼리에 테이블 이름을 가져옵니다 :

    이것은 INSERT INTO 쿼리에 테이블 이름을 가져옵니다 :

    (?<=(INTO)\s)[^\s]*(?=\(())
    

    다음은 동일하지만, 조인을 포함하는 선택으로 할 것

    (?<=(from|join)\s)[^\s]*(?=\s(on|join|where))
    

    다음과 같은 정규식을 사용하여 쿼리를 삽입에서 개최되는 단지 값을 반환하려는 경우 마지막으로 삽입에 다시가는

    (?i)(?<=VALUES[ ]*\().*(?=\))
    

    나는이 오래된 스레드 알고 있지만 다른 사람이 둘러보고 도움이 될 수

    즐겨

  10. ==============================

    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. ==============================

    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. ==============================

    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
    
  13. from https://stackoverflow.com/questions/281041/regular-expression-to-find-all-table-names-in-a-query by cc-by-sa and MIT license