programing

java에서 oracle sql 스크립트 실행

oldcodes 2023. 7. 23. 14:40
반응형

java에서 oracle sql 스크립트 실행

자바 웹 애플리케이션이 시작될 때 데이터베이스를 업그레이드해야 하는 SQL 스크립트가 많이 있습니다.

ibatis 스크립트러너를 사용하려고 했지만 트리거를 정의할 때 ";" 문자가 문의 끝을 표시하지 않는 영광스럽게 실패합니다.

이제 저는 기본적으로 작업을 수행하지만, 특히 "보기 만들기 또는 바꾸기"에서 가능한 형식과 주석을 파괴하는 스크립트 러너 버전을 작성했습니다.

public class ScriptRunner {
private final DataSource ds;


public ScriptRunner(DataSource ds) {
    this.ds = ds;
}

public void run(InputStream sqlStream) throws SQLException, IOException {
    sqlStream.reset();
    final Statement statement = ds.getConnection().createStatement();
    List<String> sqlFragments = createSqlfragments(sqlStream);
    for (String toRun : sqlFragments) {
        if (toRun.length() > 0) {
            statement.execute(toRun);
        }
    }
}

private static List<String> createSqlfragments(InputStream sqlStream) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(sqlStream));

    List<String> ret = new ArrayList<String>();
    String line;
    StringBuilder script = new StringBuilder();
    while ((line = br.readLine()) != null) {
        if (line.equals("/")) {
            ret.add(removeMultilineComments(script));
            script = new StringBuilder();
        } else {
            //strip comments
            final int indexComment = line.indexOf("--");
            String lineWithoutComments = (indexComment != -1) ? line.substring(0, indexComment) : line;
            script.append(lineWithoutComments).append(" ");
        }
    }
    if (script.length() > 0) {
        ret.add(removeMultilineComments(script));
    }
    return ret;
}

private static String removeMultilineComments(StringBuilder script) {
    return script.toString().replaceAll("/\\*(.*?)\\*/", "").trim();
}

이것을 달성할 수 있는 깨끗한 방법이 있습니까?겨울잠에서 제가 보지 못한 것이 있나요?아니면 어떻게든 sqlplus에 입력 스트림을 전달할 수 있을까요? 포맷에 대한 걱정 외에도, 저는 pl/sql 구문에 대한 지식이 제한되어 있기 때문에 이 코드가 오류가 없는지 의심스럽습니다.

아래 솔루션을 참조하여 사용하십시오. 시도하고 테스트하여 성공적으로 실행했습니다.

private static String script_location = "";
private static String file_extension = ".sql";
private static ProcessBuilder processBuilder =null;

public static void main(String[] args) {
    try {
        File file = new File("C:/Script_folder");
        File [] list_files= file.listFiles(new FileFilter() {

            public boolean accept(File f) {
                if (f.getName().toLowerCase().endsWith(file_extension))
                    return true;
                return false;
            }
        });
        for (int i = 0; i<list_files.length;i++){
            script_location = "@" + list_files[i].getAbsolutePath();//ORACLE
            processBuilder = new ProcessBuilder("sqlplus",        "UserName/Password@database_name", script_location); //ORACLE
            //script_location = "-i" + list_files[i].getAbsolutePath();
            //  processBuilder = new ProcessBuilder("sqlplus", "-Udeep-Pdumbhead-Spc-de-deep\\sqlexpress-de_com",script_location);
            processBuilder.redirectErrorStream(true);
            Process process = processBuilder.start();
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String currentLine = null;
            while ((currentLine = in.readLine()) != null) {
                System.out.println(" "  + currentLine);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }catch(Exception ex){
        ex.printStackTrace();
    }
}

이 스니펫 코드를 사용하여 실행해 보십시오.

Tansx to 사용자는 아래 링크에서 솔루션을 언급했습니다.

http://forums.sun.com/thread.jspa?threadID=5413026

안부 | 니틴

iBATIS ScriptRunner에는 다음과 같은 기능이 있습니다.setDelimiter(String, boolean)방법.이렇게 하면 ";" 이외의 문자열을 SQL 문 사이의 구분 기호로 사용할 수 있습니다.

Oracle SQL 스크립트에서 문을 "/"(슬래시)로 구분합니다.

Java 코드에서 다음을 호출하기 전에runScript을 보다setDelimter("/", false)ScriptRunner가 "/"를 문 구분 기호로 인식하도록 지시합니다.

얼마 전에도 동일한 문제가 발생하여 해결책을 검색하는 중에 귀하의 질문에 여러 번 부딪혔기 때문에 귀하께 신세를 진 것 같습니다. 지금까지 제가 발견한 사항은 다음과 같습니다.

간단히 말해서, 이에 대한 준비된 해결책은 없습니다. Ant 또는 Maven 소스를 열면 간단한 스크립트에 적합하지만 일반적으로 저장 프로시저 중 하나에 실패하는 간단한 정규식 기반 스크립트 스플리터를 사용하는 것을 볼 수 있습니다.iBATIS, c5db 마이그레이션 등과 동일한 사례.

문제는 "SQL Scripts"를 실행하려면 (1) SQL, (2) PL/SQL 및 (3) sqlplus 명령을 처리할 수 있어야 한다는 것입니다.

중입니다.sqlplus그 자체가 실제로 방법이지만 구성이 엉망이 되므로 이 옵션을 피하려고 했습니다.

Alexandre Porcelli와 같은 PL/SQL용 ANTLR 파서가 있습니다. PL/SQL 파서는 매우 가깝지만 지금까지 이를 기반으로 완벽한 드롭인 솔루션을 준비한 사람은 아무도 없습니다.

우리는 다음과 같은 일부 sqlplus 명령을 인식하는 또 다른 애드혹 스플리터를 작성하게 되었습니다./그리고.EXIT여전히 못생겼지만 대부분의 스크립트에 사용할 수 있습니다. (참고: 일부 스크립트, 예: 추적 기능이 있는 스크립트--코멘트, 효과가 없을 것입니다. 해결책이 아니라 여전히 둔탁합니다.)

sqlplus : 네 할 수 있습니다.저는 항상 Xemacs(편집자) 내에서 sqlplus를 실행합니다.따라서 sqlplus를 해석 모드로 실행한 다음 명령을 제공하고 출력을 읽을 수 있습니다.

또 다른 방법은 오라클(http://www.oracle.com/technology/software/products/sql/index.html) 에서 무료 Java 기반 SQL 개발자 도구를 다운로드하는 것입니다.자바 프로그램 위의 래퍼인 sqlcli.bat 유틸리티와 함께 제공됩니다.이 명령줄 유틸리티를 사용하여 작업을 수행할 수 있습니다.

요약하면, 저는 백그라운드에서 sqlplus를 실행하여 입력을 제공하고 출력을 읽습니다(emacs처럼).

스크립트 실행기를 직접 작성하려면 Spring JDBC의 SimpleJdbcTemplate(http://static.springframework.org/spring/docs/2.0.x/reference/jdbc.html) 를 사용하면 됩니다.

물론 봄에 리소스를 로드하는 것처럼 스크립트를 로드할 수도 있습니다.

다른 사용자의 구현을 볼 수 있습니다.다음 리소스를 참조하십시오. "Java에서 오픈 소스 SQL 클라이언트" http://java-source.net/open-source/sql-clients

언급URL : https://stackoverflow.com/questions/200513/run-oracle-sql-script-from-java

반응형