我正在尝试用非常复杂的数据填充数据库中的一个表。为此,我使用的是生成器API(它为我提供了随机数据)。
public void populateCrackers(){
PreparedStatement psm;
String queryJoke = "(SELECT jid FROM Jokes WHERE jid=?)";
String queryHat = "(SELECT hid FROM Hats WHERE hid=?)";
String queryGift = "(SELECT gid FROM Gifts WHERE gid=?)";
String query = "INSERT INTO Crackers(cid, name, jid, hid, gid, quantity) VALUES(" +
"?, " +
"?, " +
queryJoke + ", " +
queryHat + ", " +
queryGift + ", " +
"?)";
System.out.println(query);
String cracker_String = utils.JSONUtils.getJSON(crackerAPI, client);
JSONObject crackerJSON = new JSONObject(cracker_String);
JSONArray crackers = crackerJSON.getJSONArray("results");
for(int j=0; j<crackers.length(); j++){
try{
psm = connection.prepareStatement(query);
psm.setInt(1,crackers.getJSONObject(j).getInt("cid"));
psm.setString(2, crackers.getJSONObject(j).getString("cname"));
psm.setInt(3, crackers.getJSONObject(j).getInt("rjoke"));
psm.setInt(4, crackers.getJSONObject(j).getInt("rhat"));
psm.setInt(5, crackers.getJSONObject(j).getInt("rgift"));
psm.setInt(6, crackers.getJSONObject(j).getInt("cquantity"));
psm.execute();
System.out.println(crackers.getJSONObject(j).get("cid") + " "
+ crackers.getJSONObject(j).get("cname") + " "
+ crackers.getJSONObject(j).get("cquantity") + " "
+ crackers.getJSONObject(j).get("rjoke") + " "
+ crackers.getJSONObject(j).get("rhat") + " "
+ crackers.getJSONObject(j).get("rgift"));
}catch (Exception e){
e.printStackTrace();
}
}
}
这是填充“Crackers”标签的方法。我想知道这是否被接受为准备好的声明。当我在psql交互式命令行工具中运行它时,恰好是带有一些选定id的语句(例如INSERT INTO Crackers (cid, name, hid, jid, gid, quantity) VALUES('cid', 'name', (SELECT hid FROM Hats WHERE hid=11), (SELECT jid FROM Jokes where jid=99), (SELECT gid FROM Gifts WHERE gid=13), 5)
它可以完美地运行。
我的预备陈述是否打破了约束?
有什么想法吗?
LATER EDIT:不一致是null值可以到达我的Crackers表的形式(例如Cracker(1,“hello”,null,null,3,123)出现在表中。
答案 0 :(得分:2)
代码是正确的,但必须关闭准备好的语句,最好在for循环之前创建一次语句。
现在有crackers.length()
次语句创建但未关闭。这可能会带来问题。
使用try-with-resouce语法进行自动关闭,无论是否有任何异常或返回。
try (PreparedStatement psm = connection.prepareStatement(query)) {
for (int j = 0; j < crackers.length(); j++) {
...
psm.executeUpdate();
并致电executeUpdate
而不是更一般的execute
。产生的更新计数可能是有意义的(1/0)。
答案 1 :(得分:2)
Prepared声明没有任何内容。约束可以通过您设置的参数来破坏。您也可以在PreparedStatement中将PLSQL语句作为一个无限块运行。
用BEGIN围绕它......结束。只有一件事是不同的 - 对于JDBC参数是什么? mark not:PLSQL的参数,无法使用命名参数。
这意味着如果你需要为JDBC多次使用参数,你必须拥有那么多吗?标记并设置所有这些。
因此,请关注您传递给的参数及其序列。
答案 2 :(得分:1)
我意识到我的桌子上有错误的约束。我把空值放进去了。准备好的声明没有错。
创建表的正确查询是这样的:
String createCrackersQuery = "CREATE TABLE Crackers(" +
" cid INTEGER," +
" name VARCHAR NOT NULL," +
" jid INTEGER NOT NULL," +
" hid INTEGER NOT NULL," +
" gid INTEGER NOT NULL," +
" quantity INTEGER NOT NULL," +
" CONSTRAINT Cracker_Primary PRIMARY KEY (cid)," +
" CONSTRAINT Cracker_Name_Unique UNIQUE(name)," +
" CONSTRAINT Joke_Foreign FOREIGN KEY (jid) REFERENCES Jokes(jid)," +
" CONSTRAINT Hat_Foreign FOREIGN KEY (hid) REFERENCES Hats(hid), " +
" CONSTRAINT Gift_Foreign FOREIGN KEY (gid) REFERENCES Gifts(gid)" +
")";