我有一个H2名为 PRODUCTS
的数据库,包含 5000 行,每行 55 列。我当前正在使用 PreparedStatement
将值行添加到数据库,但它不会检查该行是否已存在。相反,我只需要在列名“id”(VARCHAR 类型)不包含某个字母数字字符串,并且列名“id2”(VARCHAR 类型)< em>不某个字母数字字符串,并且列名“raw_yn”(BOOLEAN 类型)包含 false
。我在准备好的语句中输入的值是通过方法提供的。
问题here与我要问的非常接近,区别在于它是 solution基于向空数据库添加行,并确保数据库为空。 H2 的创建者评论道:
Then the "where not exists" ensures this rows are only inserted if the table [TABLE] is empty.
如何调整此代码,使其仅在满足上述 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
,它如何适合我的 stmt.setString(1, id1val) 的
??.感谢您的帮助。PreparedStatement
);
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
<小时/>
更新:
根据 Gord 的建议,我编写了以下代码。如果数据库为空,n
将返回 0。向空数据库添加 5000 行大约需要 1 分钟。但是,如果存在匹配项,即使我只是使用 return
而不是使用额外的 INSERT
代码,它也会花费近 5 倍的时间。那么不是应该更快吗?
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]
最佳答案
考虑使用暂存临时表,将所有数据按原样附加到类似的结构化表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);
关于java - 如果某些值不存在则插入到表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38544120/