![](/img/trans.png)
[英]Clever way to add the same parameter to mulitple locations in a prepared-statement
[英]Does the prepared-statement work this way?
我試圖用非常復雜的數據填充數據庫中的一個表。 為此,我使用了生成器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)
可以正常工作。
我的准備陳述會打破約束嗎?
有任何想法嗎?
稍后編輯:不一致的形式是空值可以到達我的Crackers表(例如,Cracker(1,“ hello”,null,null,3,123)出現在表中。
該代碼是正確的,盡管必須關閉准備好的語句,並且最好在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)。
與Prepared語句無關。 約束可以通過您設置的參數來打破。 您也可以在PreparedStatement中將PLSQL語句作為匿名塊運行。
只需用BEGIN ...結束將其包圍即可。 唯一不同的是-JDBC參數是? 對於PLSQL,將not標記為:parameter,並且無法使用命名參數。
這意味着,如果您需要對JDBC多次使用參數,那么必須有那么多? 標記並設置所有這些標記。
因此,請注意傳遞給它們的參數及其順序。
我意識到我的桌子上約束不正確。 我讓空值進入。准備好的語句沒有錯。
創建表的正確查詢是這樣的:
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)" +
")";
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.