2010-01-15 25 views

Trả lời

15

Không có cách nào để thực hiện điều đó. Bạn có thể thực hiện một khách hàng bản địa như một chương trình bên ngoài để làm điều đó mặc dù:

import java.io.*; 
public class CmdExec { 

    public static void main(String argv[]) { 
    try { 
     String line; 
     Process p = Runtime.getRuntime().exec 
     ("psql -U username -d dbname -h serverhost -f scripfile.sql"); 
     BufferedReader input = 
     new BufferedReader 
      (new InputStreamReader(p.getInputStream())); 
     while ((line = input.readLine()) != null) { 
     System.out.println(line); 
     } 
     input.close(); 
    } 
    catch (Exception err) { 
     err.printStackTrace(); 
    } 
    } 
} 
  • mẫu mã được chiết xuất từ ​​here và sửa đổi để trả lời câu hỏi giả định rằng người dùng muốn thực hiện một tập tin PostgreSQL kịch bản.
2

Không, bạn phải đọc tệp, chia tệp thành các truy vấn riêng lẻ và sau đó thực hiện chúng riêng lẻ (hoặc sử dụng API lô của JDBC).

Một trong những lý do là mỗi cơ sở dữ liệu định nghĩa cách riêng của chúng để tách các câu lệnh SQL (một số sử dụng ;, các số khác /, một số cho phép cả hai hoặc thậm chí để xác định dấu phân tách của riêng bạn).

0

JDBC không hỗ trợ tùy chọn này (mặc dù trình điều khiển DB cụ thể có thể cung cấp tùy chọn này). Dù sao, sẽ không có vấn đề gì khi tải tất cả nội dung tập tin vào bộ nhớ.

2

Bạn không thể sử dụng JDBC vì nó không hỗ trợ. Làm việc xung quanh sẽ bao gồm iBatis iBATIS là một khuôn khổ kiên trì và gọi hàm tạo Scriptrunner như được hiển thị trong tài liệu iBatis.

của nó không tốt để bao gồm một kiên trì khuôn khổ cân nặng như ibatis để chạy một cách đơn giản script sql cách nào mà bạn có thể làm khi sử dụng dòng lệnh

$ mysql -u root -p db_name < test.sql 
+0

ibatis âm thanh tốt cho công việc này! – felipecrp

23

Có cách tuyệt vời của thực hiện các kịch bản SQL từ Java mà không đọc chúng cho mình miễn là bạn không nhớ có sự phụ thuộc vào Ant. Theo ý kiến ​​của tôi, một sự phụ thuộc như vậy là rất hợp lý trong trường hợp của bạn. Đây là mẫu mã, nơi SQLExec lớp sống ở ant.jar:

private void executeSql(String sqlFilePath) { 
    final class SqlExecuter extends SQLExec { 
     public SqlExecuter() { 
      Project project = new Project(); 
      project.init(); 
      setProject(project); 
      setTaskType("sql"); 
      setTaskName("sql"); 
     } 
    } 

    SqlExecuter executer = new SqlExecuter(); 
    executer.setSrc(new File(sqlFilePath)); 
    executer.setDriver(args.getDriver()); 
    executer.setPassword(args.getPwd()); 
    executer.setUserid(args.getUser()); 
    executer.setUrl(args.getUrl()); 
    executer.execute(); 
} 
+0

Tôi đã thử điều này đối với một vài kịch bản lệnh SQL của Oracle, nó hoạt động cho 'chèn',' tạo bảng'. Nhưng đối với kịch bản có 'tạo hoặc thay thế trigger' nó không thành công với ** java.sql.SQLSyntaxErrorException: ORA-00900: câu lệnh SQL không hợp lệ ** –

+0

Có lẽ nên xem xét các dấu phân cách của bạn – carpinchosaurio

0

Hãy thử mã này:

String strProc = 
     "DECLARE \n" + 
     " sys_date DATE;"+ 
     "" + 
     "BEGIN\n" + 
     "" + 
     " SELECT SYSDATE INTO sys_date FROM dual;\n" + 
     "" + 
     "END;\n"; 

try{ 
    DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver()); 
    Connection connection = DriverManager.getConnection ("jdbc:oracle:thin:@your_db_IP:1521:your_db_SID","user","password"); 
    PreparedStatement psProcToexecute = connection.prepareStatement(strProc); 
    psProcToexecute.execute(); 
}catch (Exception e) { 
    System.out.println(e.toString()); 
} 
+8

Ví dụ của bạn quá đơn giản. Câu lệnh 'thường có thể chỉ thực hiện một câu lệnh SQL tại một thời điểm. Câu hỏi ngụ ý có một số lượng lớn các truy vấn hoặc chèn liên quan, và do đó chúng cần phải được chia thành các câu lệnh riêng lẻ bằng cách tìm các dấu tách. – BoffinbraiN

+0

Đồng ý, giải pháp này sẽ không hoạt động trên các tập lệnh đa lệnh. Sử dụng jisql như được đề xuất bên dưới. –

1

Từ JDBC không hỗ trợ tùy chọn này là cách tốt nhất để giải quyết câu hỏi này đang thực hiện lệnh dòng thông qua Chương trình Java. Dưới đây là ví dụ về postgresql:

private void executeSqlFile() { 
    try { 
     Runtime rt = Runtime.getRuntime(); 
     String executeSqlCommand = "psql -U (user) -h (domain) -f (script_name) (dbName)"; 
     Process pr = rt.exec(); 
     int exitVal = pr.waitFor(); 
     System.out.println("Exited with error code " + exitVal); 
     } catch (Exception e) { 
     System.out.println(e.toString()); 
     } 
} 
2

thư viện bay theo trục là thực sự tốt cho việc này:

Flyway flyway = new Flyway(); 
    flyway.setDataSource(dbConfig.getUrl(), dbConfig.getUsername(), dbConfig.getPassword()); 
    flyway.setLocations("classpath:db/scripts"); 
    flyway.clean(); 
    flyway.migrate(); 

này quét các địa điểm cho các kịch bản và chạy chúng theo thứ tự. Kịch bản có thể được phiên bản với V01__name.sql vì vậy nếu chỉ di chuyển được gọi thì chỉ những người chưa chạy sẽ được chạy. Sử dụng bảng có tên 'schema_version' để theo dõi mọi thứ. Nhưng cũng có thể làm những việc khác, xem tài liệu: flyway.

Cuộc gọi sạch sẽ không bắt buộc, nhưng hữu ích để bắt đầu từ một DB sạch. Ngoài ra, hãy lưu ý vị trí (mặc định là "classpath: db/migration"), không có dấu cách sau dấu ':', dấu trang đó bắt được tôi.

1

Công cụ bên ngoài đơn giản nhất mà tôi thấy cũng có thể di động là jisql - https://www.xigole.com/software/jisql/jisql.jsp. Bạn sẽ chạy nó như:

java -classpath lib/jisql.jar:\ 
      lib/jopt-simple-3.2.jar:\ 
      lib/javacsv.jar:\ 
      /home/scott/postgresql/postgresql-8.4-701.jdbc4.jar 
    com.xigole.util.sql.Jisql -user scott -password blah  \ 
    -driver postgresql          \ 
    -cstring jdbc:postgresql://localhost:5432/scott -c \; \ 
    -query "select * from test;" 
+0

Tôi đã sử dụng 'java -classpath lib/jisql-2.0.11.jar: lib/jopt-simple-3.2.jar: lib/javacsv.jar: ../ ojdbc7.jar com.xigole.util.sql.Jisql -user ecm -password TODO -driver oracle.jdbc.OracleDriver -cstring jdbc: oracle: thin: @localhost: 1521: XE -c \; -input myoracle.sql' và nó hoạt động hoàn hảo. –

Các vấn đề liên quan