我正在寻找一种通过命令行以可读方式转储 SQL 查询结果的简单方法。我必须对所有类型的数据库(oracle、mysql、sybase、postgres...)执行此操作,因此我使用 JDBC。我需要将转储文件保存在我的本地计算机(而不是服务器)上。
我有一个包含所有驱动程序的主 java 存档,通常当我使用 JDBC(通过 python)连接到数据库时,我需要指定驱动程序和驱动程序类的路径。
目标是运行类似的东西
<tool> <jdbc-URL> <driver location> <driver class> <login> <pwd> <query> <output file>
例如使用 java 存档
java Tool.jar 'jdbc:sybase:db.com:11/sys' # <jdbc-URL>
'path/to/JDBCsybaseDriver.jar' # <driver location>
'com.sybase.jdbc3.jdbc.SybDriver' # <driver class>
'root' '' # <login> <pwd>
'SELECT * FROM <tab> WHERE <cond>' # <query>
'output.csv' # <output file>
并获取正确的 csv 文件
PID;Name;IsDead
144;Mike;True
266;Carl;False
984;Anna;False
你知道有什么工具可以做到这一点吗?
我不知道如何自己编写这个,而且我对 java 不太熟悉,所以如果您想出一些代码,请提供有关如何将其构建为可执行 java 存档的解释
最佳答案
这是一个基本应用程序,用于将 SQL 查询的输出写入以 ; 分隔的文件:
import java.io.File;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Properties;
public class SqlOut {
public static Connection getConnection(String url, String user, String pw) throws SQLException {
Connection conn = null;
Properties connectionProps = new Properties();
connectionProps.put("user", user);
connectionProps.put("password", pw);
conn = DriverManager.getConnection(url, connectionProps);
return conn;
}
private static String coalesce(Object o, String nullValue)
{
if(o==null)
return nullValue;
return o.toString();
}
/**
*
* @param args
* [0] : jdbc connection url
* [1] : JDBC driver class name
* [2] : database user
* [3] : database password
* [4] : SQL statement
* [5] : output file name
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Class.forName(args[1]);
Connection conn = getConnection(args[0], args[2], args[3]);
PreparedStatement ps = conn.prepareStatement(args[4]);
ResultSet rs = ps.executeQuery();
ResultSetMetaData rsmeta = rs.getMetaData();
File outfile=new File(args[5]);
try (FileWriter fos = new FileWriter(new File(args[5]))) {
// export column names
for (int ci = 1; ci <= rsmeta.getColumnCount(); ci++) {
if (ci > 1)
fos.write(";");
fos.write(rsmeta.getColumnLabel(ci));
}
fos.write("\n");
while (rs.next()) {
for (int ci = 1; ci <= rsmeta.getColumnCount(); ci++) {
if(ci > 1)
fos.write(";");
fos.write(coalesce(rs.getObject(ci),""));
}
fos.write("\n");
}
}
System.out.println("CSV file written to "+outfile.getAbsolutePath());
}
}
该代码不包含除 java 运行时之外的任何依赖项,并且没有包声明,因此可以轻松编译:
DOS> javac SqlOut.java
假设您的类路径中有可用的 Java JDK。
启动应用程序时,驱动程序 jar 必须在类路径中可用,以便您通过类路径传递它,而不是作为应用程序的参数。
调用此命令的命令(在 DOS 提示符下):
DOS> java -classpath .;\path\to\driver.jar SqlOut jdbc:db:serverurl org.postgresql.Driver user pw "select * from myTable where 1=1" out.csv
不要在参数两边加上引号(SQL 语句除外,因为它包含空格)。 在 unix 上,类路径分隔符是 : 而不是 ;
编辑:标题行的固定分隔符:,替换为 ;
关于java - 如何在 CSV 中提取使用 JDBC 的查询结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56670834/