【问题标题】:Check to see if a column value exists prior to insert into SQL Server在插入 SQL Server 之前检查列值是否存在
【发布时间】:2014-10-17 02:49:24
【问题描述】:

使用 JSoup 解析 HTML,然后将行插入 MS SQL Server DB。为避免重复,我需要在插入执行之前检查 guid 是否存在。该代码有效,只是我无法在 guid 上获得验证。请参阅插入块中的 Select 语句。返回以下错误:

线程“main”中的异常 com.microsoft.sqlserver.jdbc.SQLServerException:多部分 无法绑定标识符“FeedMessage.guid”。在 com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216) 在 com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515) 在 com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:404) 在 com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350) 在 com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696) 在 com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715) 在 com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180) 在 com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:155) 在 com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(SQLServerPreparedStatement.java:314) 在 Archiver.Database.writer(Database.java:58) 在 RSS.Test.main(Test.java:35) Java 结果:1

    // Need to use this class for all of the DB-related interactions. 
    // Add methods to this class for added capabilities from within the GUI
package Archiver;

import RSS.FeedMessage;
import RSS.Test;
import Scraper.Scraping;
import java.sql.*;

/**
 *
 * @author joel.ramsey
 */
public class Database {

    Statement stmt;

    String DriverName;
    String url = "jdbc:sqlserver://sss.ss.ss.ss:1433;databaseName=TextAnalytics";
    String DBuser = "xx";
    String DBpassword = "xxxxxx";

    //Method to connect to the DB upon initialization
    public void connectionText() throws ClassNotFoundException, SQLException {

        try (Connection con = DriverManager.getConnection(this.url, this.DBuser, this.DBpassword);) {

            if (con != null) {
                DatabaseMetaData dm = (DatabaseMetaData) con.getMetaData();
                System.out.println("Driver name: " + dm.getDriverName());
                System.out.println("Driver version: " + dm.getDriverVersion());
                System.out.println("Product name: " + dm.getDatabaseProductName());
                System.out.println("Product version: " + dm.getDatabaseProductVersion());
            }

        } catch (Exception e) {
            System.err.println("Got an exception...");
            System.err.println(e.getMessage());

        }

    }

    //Method to write the parsed content of the RSS source article to the DB.
    public void writer(String Title, String Description, String Link, String Author, String guid, String contents) throws SQLException, ClassNotFoundException {
        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        Connection con = null;
        PreparedStatement writeStmt = null;
        ResultSet rs = null;
        try {
            con = DriverManager.getConnection(this.url, this.DBuser, this.DBpassword);
            writeStmt = con.prepareStatement("IF NOT EXISTS (SELECT TextAnalytics FROM Archive_Source WHERE guid = FeedMessage.guid) INSERT INTO Archive_Source(title,description,link,author,guid,contents) VALUES (?,?,?,?,?,?)");
            writeStmt.setString(1, Title);
            writeStmt.setString(2, Description);
            writeStmt.setString(3, Link);
            writeStmt.setString(4, Author);
            writeStmt.setString(5, guid);
            writeStmt.setString(6, contents);
            writeStmt.executeUpdate();
        } finally {
            close(con, writeStmt, rs);
        }
    }

    //Method to close the connection manually. Called at the conclusion of each DB contact job.
    protected void close(Connection conn, Statement stmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
            }
        }
    }

    //Method to delete all contents from the table. Should be called from the GUI
    public void delete(String Title, String Description, String Link, String Author, String guid, String contents) throws SQLException, ClassNotFoundException {
        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        Connection con = null;
        PreparedStatement writeStmt = null;
        ResultSet rs = null;
        try {
            con = DriverManager.getConnection(this.url, this.DBuser, this.DBpassword);
            writeStmt = con.prepareStatement("DELETE * FROM Archive_Source");
            writeStmt.executeUpdate();
        } finally {
            close(con, writeStmt, rs);
        }
    }
}

【问题讨论】:

  • 什么是“FeedMessage”?我在您的查询中没有看到该表或表别名。我认为您想创建另一个具有相同 guid 值的参数,并在 EXISTS 子查询中指定它而不是“FeedMessage.guid”。

标签: java sql-server jsoup


【解决方案1】:

您的 SQL 语句中有几处错误。我把它分成多行,这样答案更容易阅读。

" IF NOT EXISTS (SELECT TextAnalytics FROM Archive_Source " +
" WHERE guid = FeedMessage.guid) INSERT INTO " +
" Archive_Source(title,description,link,author,guid,contents) " +
" VALUES (?,?,?,?,?,?)") "
  1. 什么是FeedMessage.guid?如果FeedMessage是一个表,则需要在FROM语句中引用。
  2. 您正在为 6 个INSERT 语句参数设置值,但不是为guid 函数参数设置值。在你说WHERE guid = FeedMessage.guid 的部分中,你不应该也参数化guid,或者像这样连接值。 "WHERE '" + guid + "'= FeedMessage.guid"。

所以如果我对你的代码的假设是正确的,那么代码应该如下。

    try {
        con = DriverManager.getConnection(this.url, this.DBuser, this.DBpassword);
        writeStmt = con.prepareStatement(
                         " IF NOT EXISTS (SELECT TextAnalytics " +
                         " FROM Archive_Source WHERE guid = ?) " +
                         " INSERT INTO Archive_Source " +                                                          
                         " (title,description,link,author,guid,contents) " +
                         " VALUES (?,?,?,?,?,?) )";
        writeStmt.setString(1, guid);
        writeStmt.setString(2, Title);
        writeStmt.setString(3, Description);
        writeStmt.setString(4, Link);
        writeStmt.setString(5, Author);
        writeStmt.setString(6, guid);
        writeStmt.setString(7, contents);
        writeStmt.executeUpdate();
    } finally {
        close(con, writeStmt, rs);
    }

请注意,我删除了 FeedMessage.guid 并将其替换为 guid 参数,并假设该比较的左侧是 Archive_Source 表中名为 guid 的字段。

【讨论】:

  • FeedMessage 是一个 Java 类文件,我们从已解析的 HTML 中获取我们的 guid 值。我试图在插入之前查看它是否存在于数据库中。
  • 哦,那么它应该在包含 select 语句的 " 引号之外,并连接到其中。
猜你喜欢
  • 2021-08-18
  • 1970-01-01
  • 2016-06-24
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
  • 2022-12-20
  • 1970-01-01
  • 2015-12-17
相关资源
最近更新 更多