我有一个名为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]
答案 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);