2013-05-21 4 views
2

문자열에서 SQL 쿼리를 추출하는 정규식이 있습니까? 나는 이 아니며은 SQL 구문의 유효성을 검사하고 SQL 명령을 추출하는 데 관심이 있습니다. 주어진 SQL 파일/문자열을 유연하게 구문 분석합니다.SQL 쿼리를 추출하는 정규 표현식

SELECT 
    * 
FROM 
    test_table 
WHERE 
    test_row = 'Testing ; semicolon'; 

SELECT * FROM another_test_table; 

INSERT INTO 
    table_name 
VALUES 
    (value1,'value which contains semicolon ;;;;',value3,...); 

일부 의사 코드 예제는 다음과 같습니다 : 감안할 때

는 다음과 같은 SQL 파일/문자열 예입니다 ^(UPDATE|SELECT|INSERT INTO)(.*)(;)$. 앞으로 모든 (가능한) 명령을 사용하여이 기능을 확장하고자합니다. 로 시작 일치

  • 찾는 중 : (UPDATE | SELECT | INSERT | INTO) (공백과 줄 바꿈 포함)
  • 0 개 이상의 any character SQL 쿼리를 구분합니다 ;에서
  • 중지합니다.

이 정규식을 통해 가능할 것이다 때마다 다음과 같은 자바 코드를 추출 할 수있는 모든 SQL 명령 :

final String regex = "LOOKING_FOR_THIS_ONE"; 
final Pattern p = Pattern.compile(regex, Pattern.MULTILINE); 
final Matcher matcher = p.matcher(content); 

while (matcher.find()) { 
    // matcher.group() now contains the full SQL command 
} 

사전에 감사!

+1

인생을 힘들게 만들지 말고, 쿼리를 속성 키 (모든 키 포함)에 넣고로드 한 다음 valueSet을 반복합니다. –

+0

가능한 해결책은 아니므로 작업해야하므로 입력 형식을 요구할 수 없습니다. 입력은 SQL 명령을 포함하는 텍스트 파일입니다. 추출/구문 분석이 필요합니다. – Velth

+3

해당 문자열을 만든 사람이 누구나 ...을 포함 할 가능성이 있습니까? 구조화 된 정보에 평범한 텍스트를 사용하고 개발자가 그 정보를 가지고 살도록 강요하는 것은 고의적 인 잔혹한 것처럼 보입니다. –

답변

0

(?m)^(UPDATE|SELECT|INSERT INTO).*;$. 이것은 패턴을 뉴 라인 위에 매칭되도록 확장합니다. 루프를 통해 모든 SQL을 찾을 수 있어야합니다.

제공된 예제를 보면 ;까지 명령과 일치합니다. here을 테스트하는 데 사용 된 예제를 볼 수 있습니다.

0

언어를 다루는 경우 문자열을 토큰 화하는 렉서를 만듭니다. 어휘 분석기 생성기 인 JFlex을 사용하십시오. 특수 파일에 지정된 문법에 따라 문자열을 토큰으로 분할하는 Java 클래스를 생성합니다. 관련 문법 규칙을 this file에서 가져옵니다.

구문 분석은 토큰 화 (또는 어휘 분석)와는 별도의 프로세스입니다. 렉시 컬 분석이 충분하지 않으면 구문 분석기를 사용하여 파서 생성기를 사용할 수 있습니다.

1

세미콜론이 해당 행의 마지막 공백이 아닌 문자 인 경우 "올바르게"일치시킬 수 있습니다.

final String regex = ^(SELECT|UPDATE|INSERT)[\s\S]+?\;\s*?$ 

final Pattern p = Pattern.compile(regex, Pattern.MULTILINE); 
final Matcher matcher = p.matcher(content); 
+0

다중 행 SQL 쿼리에서도 작동합니다. 감사! –

2

나는이 그 일을하는 좋은 방법이 아니라고 말함으로써 시작, 강하게, 양호하게는 진술 한 위치 제대로 태그, 그것을하는 다른 방법을 찾을 수 있도록 촉구 것이다 돈 당신 때문에 이 상황에서는 끝나지 않습니다.

SQL에 따르면 SQL은 다음 중 하나에서 시작해야합니다. DELETE, SELECT, WITH, UPDATE 또는 INSERT INTO. 또한 입력이 ;으로 끝나야합니다.

우리는 다음과 같이 SQL과 일치하는 모든 시퀀스를 잡기 위해 이것을 사용할 수 있습니다 :

final String regex = "^(INSERT INTO|UPDATE|SELECT|WITH|DELETE)(?:[^;']|(?:'[^']+'))+;\\s*$"; 
final Pattern p = Pattern.compile(regex, Pattern.MULTILINE | Pattern.DOTALL); 

그룹 1은 이제 경우에 당신이 UPDATE 또는 SELECT에 유효한 SQL을 필터링 할 운영 말씀을 보유하고 있습니다. 이 작업을 수행 할 수 있다는 것을 의미

https://regex101.com/r/dt9XTK/2

0

SQL은 모든 문을 찾기 위해 문맥을해야합니다 충분히 복잡 :

행동의 정규식뿐만 아니라 여기에-에서 동굴을보기 정규식으로 예를 들어

:

SELECT Model FROM Product 
WHERE ManufacturerID IN (SELECT ManufacturerID FROM Manufacturer 
WHERE Manufacturer = 'Dell') 

(예 http://www.sql-tutorial.com/sql-nested-queries-sql-tutorial/에서 온다). 중첩 된 쿼리는 여러 번 중첩 될 수 있고 다른 값으로 시작될 수 있습니다. 사용자가 관심있는 하위 집합에 대한 정규 표현식을 작성할 수 있으면 읽을 수 없습니다.

ANTLRSQL 2003 grammar입니다 (아직 시도하지 않았습니다).

관련 문제