Java 如何在CSV中使用JDBC提取查询结果

Java 如何在CSV中使用JDBC提取查询结果,java,csv,jdbc,jar,Java,Csv,Jdbc,Jar,我正在寻找一种通过命令行以可读的方式转储SQL查询结果的简单方法。我必须对所有类型的数据库(oracle、mysql、sybase、postgres…)都这样做,所以我使用JDBC。我需要转储文件位于本地计算机(而不是服务器)上 我有一个包含所有驱动程序的主java存档,通常当我使用JDBC(通过python)连接到数据库时,我需要指定驱动程序和驱动程序类的路径 目标是运行类似于 <tool> <jdbc-URL> <driver location> <

我正在寻找一种通过命令行以可读的方式转储SQL查询结果的简单方法。我必须对所有类型的数据库(oracle、mysql、sybase、postgres…)都这样做,所以我使用JDBC。我需要转储文件位于本地计算机(而不是服务器)上

我有一个包含所有驱动程序的主java存档,通常当我使用JDBC(通过python)连接到数据库时,我需要指定驱动程序和驱动程序类的路径

目标是运行类似于

<tool> <jdbc-URL> <driver location> <driver class> <login> <pwd> <query> <output file>
你知道有什么工具可以做到这一点吗


我不知道我自己怎么写这个,我对java不是很熟悉,所以如果你想得到一些代码,请解释如何将其构建到可执行的java归档文件中-分离文件:

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());
    }
}
假设类路径中有一个可用的JavaJDK

在启动应用程序时,驱动程序jar必须在类路径中可用,以便通过类路径传递,而不是作为应用程序的参数

调用此命令(从DOS提示符):

除了SQL语句外,不要在参数周围加引号,因为它包含空格。 在unix上,类路径分隔符是:而不是


编辑:标题行的固定分隔符:,替换人

这是一个基本应用程序,用于将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());
    }
}
假设类路径中有一个可用的JavaJDK

在启动应用程序时,驱动程序jar必须在类路径中可用,以便通过类路径传递,而不是作为应用程序的参数

调用此命令(从DOS提示符):

除了SQL语句外,不要在参数周围加引号,因为它包含空格。 在unix上,类路径分隔符是:而不是


编辑:标题行的固定分隔符:,替换人

谢谢!!如果
rs.getObject(ci)
返回一个包含分号的字符串,例如
“TL;DR”
,会发生什么?另外,为什么第一行(列标题)用逗号分隔,而后面的行(数据)用分号分隔?可能是打字错误。我将在参数中添加分隔符。处理出现在值中的分隔符的最佳方法是什么?好的,所以我几乎立刻就让它工作了(谢谢你的解释!!)。我会玩分离器,但除此之外,它是完美的,谢谢!!非常感谢。如果
rs.getObject(ci)
返回一个包含分号的字符串,例如
“TL;DR”
,会发生什么?另外,为什么第一行(列标题)用逗号分隔,而后面的行(数据)用分号分隔?可能是打字错误。我将在参数中添加分隔符。处理出现在值中的分隔符的最佳方法是什么?好的,所以我几乎立刻就让它工作了(谢谢你的解释!!)。我会玩分离器,但除此之外,它是完美的,谢谢!!
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());
    }
}
DOS> javac SqlOut.java
DOS> java -classpath .;\path\to\driver.jar SqlOut jdbc:db:serverurl org.postgresql.Driver user pw "select * from myTable where 1=1" out.csv