如果某些值不存在,请插入表格

时间:2016-07-23 16:43:06

标签: java sql database jdbc h2

我有一个名为PRODUCTS的{​​{3}}数据库,每行有5000行和55列。我目前正在使用PreparedStatement向数据库添加值行,但它不会检查该行是否已存在。相反,我只需要插入行,如果列名称" id" (类型VARCHAR)包含某个字母数字字符串,如果列名称" id2" (类型VARCHAR)某个字母数字字符串,如果列名称" raw_yn" (类型BOOLEAN)包含false。我在准备好的陈述中输入的值是通过一种方法提供的。

问题H2与我提出的问题非常接近,不同之处在于here基于向空数据库添加行,以及确保数据库为空。 H2的创建者评论说:

  

然后"哪里不存在"确保仅在插入时才插入此行   table [TABLE]是空的。

如何调整此代码,以便只满足上述3个要求(DB是否为空)时才执行INSERT查询?

目前我有:

 import java.sql. *;
       static final String JDBC_DRIVER = "org.h2.Driver";
       static final String DB_URL = "jdbc:h2:~/myDB";
       static final String USER = "test";
       static final String PASS = "test";
       static final Connection conn = null;
       static final Statement stmt = null;

       public class DataBaseManager {

           public void insertIntoDB(String id1val, String id2val, Boolean raw_yn_val, ...,...) {

               try {
                   Class.forName(JDBC_DRIVER);
                   conn = DriverManager.getConnection(DB_URL, USER, PASS);
                   myStatement = "INSERT INTO PRODUCTS VALUES(?,?,?,..,...)";
                   stmt = conn.prepareStatement(myStatement);
                   stmt.setString(1, id1val);
                   stmt.setString(2, id2val);
                   stmt.setBoolean(3, raw_yn_val);
                   stmt.setString(4,....);
                // Continue up to 55
                   stmt.executeUpdate();
               }

                 [catch&finally blocks]
           }
       }

myStatement应该更改为什么?我很困惑,因为如果我使用下面的select 0, 'id1' union,那么它如何适合PreparedStatement stmt.setString(1, id1val);的{​​{1}}。谢谢你的帮助。

INSERT INTO PRODUCTS SELECT * FROM(
select 0, 'id1' union                         // <--- How does this fit into Prepared Statement?
select 1, 'id2' union
select 2, 'raw_yn' union
) x where not exists(SELECT * FROM PRODUCTS);  // <--- Ensures only works when empty

更新

根据戈德的建议,我将以下代码放在一起。如果数据库为空,n将返回0.这需要大约1分钟才能向空数据库添加5000行。但是,如果匹配,它的使用时间会延长近5倍,即使我只使用return而不是使用其他INSERT代码。所以不应该更快吗?

try {
   Class.forName(JDBC_DRIVER);
   conn = DriverManager.getConnection(DB_URL, USER, PASS);
   statement = conn.createStatement();

   String sql = "SELECT COUNT(*) AS n FROM PROPERTIES WHERE id1='" + id1 + "' AND id2='" + id2 + "' AND raw_yn='true'";
   rs = statement.executeQuery(sql);
   rs.next();
   if (rs.getInt("n") == 0) {
    Class.forName(JDBC_DRIVER);
    conn = DriverManager.getConnection(DB_URL, USER, PASS);
    myStatement = "INSERT INTO PROPERTIES VALUES(?,?,?,...)";
    stmt = conn.prepareStatement(myStatement);
    stmt.setString(1, id1);
    stmt.setString(2, id2);
    stmt.setBoolean(3, raw_yn);
    stmt.executeUpdate();
   } else {
    return; // <-- Takes 5x longer to go through ???
   }

  }

    [catch & finally blocks]

1 个答案:

答案 0 :(得分:1)

考虑使用临时临时表,将所有数据按原样附加到类似的结构化表 ProductsTemp 中,然后迁移到最终表 Products ,过滤为独特的行。下面是按此顺序合并到Java代码中的SQL语句:

分段追加(两个陈述)

DELETE FROM ProductsTemp;

INSERT INTO ProductsTemp VALUES (?,?,?,..,...);

最终迁移

INSERT INTO Products (id, id2, raw_yn, ...)
SELECT id, id2, raw_yn, ...
FROM ProductsTemp temp
WHERE NOT EXISTS (SELECT 1 FROM Products sub
                   WHERE sub.id = temp.id
                     AND sub.id2 = temp.id2
                     AND sub.raw_yn = temp.raw_yn);