簡體   English   中英

預備陳述是否以這種方式工作?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM