import java.sql.*; import java.io.*;
/** * 执行SQL语句的demo. **/ public class ExecuteSQL { public static void main(String[] args) { Connection conn = null; // 定义连接数据库的JDBC Connection对象 try { String driver = null, url = null, user = "", password = "";
// 读取输入的参数 for(int n = 0; n < args.length; n++) { if (args[n].equals("-d")) driver = args[++n]; else if (args[n].equals("-u")) user = args[++n]; else if (args[n].equals("-p")) password = args[++n]; else if (url == null) url = args[n]; else throw new IllegalArgumentException("Unknown argument."); }
// 数据库的url参数必须输入. if (url == null) throw new IllegalArgumentException("No database specified");
// 如果启动程序的时候输入了驱动,那么使用用户输入的参数动态注册数据库驱动 if (driver != null) Class.forName(driver);
// 建立到数据库的连接。jdbc会使用它所知道的所有的数据库驱动来建立与数据库的连接。 conn = DriverManager.getConnection(url, user, password);
// 创建statement对象来与数据库进行交互 Statement s = conn.createStatement();
//从命令提示符中读取sql命令 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
//循环执行用户输入的sql语句 while(true) { System.out.print("sql> "); // 提示用户可以继续输入 System.out.flush(); // 显示提示符. String sql = in.readLine(); // 读取用户输入
// 输入“quit”,退出程序. if ((sql == null) || sql.equals("quit")) break;
// 忽略空行输入 if (sql.length() == 0) continue; // 执行输入的sql命令,并显示执行结果. try { // 使用execute进行判断用户输入的是查询还是更新,如果是更新则返回”假“
boolean status = s.execute(sql); // 一些复杂的查询返回不只一个记录集,所以循环读取所有的记录集 do { if (status) { //status为”真“,查询并返回记录集 ResultSet rs = s.getResultSet(); // 读取记录集 printResultsTable(rs, System.out); // 显示记录集 } else { // status为”假“,进行更新操作,并返回操作所影响的行数 int numUpdates = s.getUpdateCount(); System.out.println("Ok. " + numUpdates + " rows affected."); }
// 判断是否有更多的记录集 status = s.getMoreResults(); } while(status || s.getUpdateCount() != -1); } // 如果sql语句执行出错,打印出错信息 catch (SQLException e) { System.err.println("SQLException: " + e.getMessage()+ ":" + e.getSQLState()); } finally { // 打印所有的警告信息 SQLWarning w; for(w=conn.getWarnings(); w != null; w=w.getNextWarning()) System.err.println("WARNING: " + w.getMessage() + ":" + w.getSQLState()); } } } //打印连接数据库失败等错误信息,并显示出来 catch (Exception e) { System.err.println(e); if (e instanceof SQLException) System.err.println("SQL State: " + ((SQLException)e).getSQLState()); System.err.println("Usage: java ExecuteSQL [-d <driver>] " + "[-u <user>] [-p <password>] <database URL>"); }
// 每次退出程序或程序出现错误时关闭数据库连接。关闭数据库连接的同时也关闭了所有打开的statements和记录集 finally { try { conn.close(); } catch (Exception e) {} } } /** * printResultsTable方法输出记录集的内容,此方法依赖于ResultSetMetaData类 **/ static void printResultsTable(ResultSet rs, OutputStream output) throws SQLException { // 建立输出流 PrintWriter out = new PrintWriter(output); // 读取记录集 ResultSetMetaData metadata = rs.getMetaData(); int numcols = metadata.getColumnCount(); // 列的数目 String[] labels = new String[numcols]; // 列标题 int[] colwidths = new int[numcols]; int[] colpos = new int[numcols]; int linewidth; linewidth = 1; for(int i = 0; i < numcols; i++) { // 保存每一列的位置和标签 colpos[i] = linewidth; labels[i] = metadata.getColumnLabel(i+1);
int size = metadata.getColumnDisplaySize(i+1); if (size == -1) size = 30; if (size > 500) size = 30; int labelsize = labels[i].length(); if (labelsize > size) size = labelsize; colwidths[i] = size + 1; linewidth += colwidths[i] + 2; }
StringBuffer divider = new StringBuffer(linewidth); StringBuffer blankline = new StringBuffer(linewidth); for(int i = 0; i < linewidth; i++) { divider.insert(i, '-'); blankline.insert(i, " "); }
for(int i=0; i<numcols; i++) divider.setCharAt(colpos[i]-1,'+'); divider.setCharAt(linewidth-1, '+'); out.println(divider);
StringBuffer line = new StringBuffer(blankline.toString()); line.setCharAt(0, '|'); for(int i = 0; i < numcols; i++) { int pos = colpos[i] + 1 + (colwidths[i]-labels[i].length())/2; overwrite(line, pos, labels[i]); overwrite(line, colpos[i] + colwidths[i], " |"); }
out.println(line); out.println(divider); // 使用next()方法遍历记录集,使用getObject方法获得列的数值并输出 while(rs.next()) { line = new StringBuffer(blankline.toString()); line.setCharAt(0, '|'); for(int i = 0; i < numcols; i++) { Object value = rs.getObject(i+1); if (value != null) overwrite(line, colpos[i] + 1, value.toString().trim()); overwrite(line, colpos[i] + colwidths[i], " |"); } out.println(line); }
out.println(divider); out.flush(); }
static void overwrite(StringBuffer b, int pos, String s) { int slen = s.length(); int blen = b.length(); if (pos+slen > blen) slen = blen-pos; for(int i = 0; i < slen; i++) b.setCharAt(pos+i, s.charAt(i)); } } 执行时如下所示:
javac ExecuteSQL.java
java ExecuteSQL -d com.microsoft.jdbc.sqlserver.SQLServerDrive r -u username -p password jdbc:microsoft:sqlserver://localhost:1433;databaseName=pubs |