INSERT und Update Hilfe

03/17/2020 12:35 Hugo081#1
Hallo ,ich habe der zeit folgendes Problem.
ich bin derzeit daran ein INSERT zu bauen was auch soweit funktioniert
hier der code

leider ist mein Problem das jedes mal eine neue zeile angelegt wird
ich möchte es aber so haben das wenn INSERT ausgeführt wurde und die itemId schon vorhanden ist das amount geupdatet wird.

leider habe ich da keine Idee weiter wenn ich UPDATE mit einfüge wird INSERT nicht mehr ausgeführt .

Ich bitte um hilfe da ich mit meinem Latein am ende bin und noch recht unerfahren in diesem Bereich . danke schonmal im vorraus
mfg Hugo
03/17/2020 14:23 Mikesch01#2
Prüf als erstes ob es schon einen Eintrag mit dieser ItemID gibt. (SELECT)

Dann mittels Code entscheidest du eben ob du ein INSERT oder UPDATE Befehl ausführen willst.
03/17/2020 14:31 Hugo081#3
Quote:
Originally Posted by Mikesch01 View Post
Prüf als erstes ob es schon einen Eintrag mit dieser ItemID gibt. (SELECT)

Dann mittels Code entscheidest du eben ob du ein INSERT oder UPDATE Befehl ausführen willst.
Dessen bin ich mir bewust frage ist nur wie setze ich das um .

hier einmal mehr vom code

Code:
mp.events.add("server:inventory:setDestroyItem", (player, itemId) => {
    if (mp.players.exists(player)) player.setVariable("destroyItemId", itemId);
});
mp.events.add("server:inventory:setGiveItem", (player, itemId) => {
    if (mp.players.exists(player)) player.setVariable("giveItemId", itemId);
});

mp.events.add("inputValueShop", (player, trigger, output) => {
    if (mp.players.exists(player)) {
        if (trigger === "DestroyItem") {
            var itemId = player.getVariable("destroyItemId");
        gm.mysql.handle.query("SELECT id, amount FROM user_items WHERE id = ? AND charId = ?", [itemId, player.data.charId], function(err, res) {
                //gm.mysql.handle.query("INSERT INTO user_items (id,charId,itemId,amount) VALUES('',?,?,?)", [currentTarget.data.charId, item.itemId, newGivenUserAmount], function(err3, res3) {
                // ON DUPLICATE KEY UPDATE c1 = VALUES(c1) + 1;   
                
                
                gm.mysql.handle.query("INSERT INTO lager (`charId`,`itemId`,`amount`)  SELECT charId,itemId,1  FROM user_items WHERE id = ? AND charId = ? ", [itemId, player.data.charId], function (err2,res2) {
                
                    if (err) console.log("Error in Get Destroy Item Query: " + err);
                else {
                    if (res.length > 0) {
                        res.forEach(function(item) {
                            if (parseInt(item.amount) >= parseInt(output)) {
                                if (output > 0) {
                                    if (parseInt(item.amount) == parseInt(output)) {
                                        gm.mysql.handle.query("DELETE FROM user_items WHERE id = ? AND charId = ?", [itemId, player.data.charId], function(err2, res2) {
                                            
                                            if (err2) console.log("Error in Destroy Item Query: " + err2);
                                            else {
                                                player.notify("Du hast den Gegenstand weggeworfen.");
                                                mp.events.call("server:inventory:prepareMenu", player);
                                            }
                                        });
                                
                                    } else {
                                        var newAmount = parseInt(parseInt(item.amount) - parseInt(output));
                                       
                                        gm.mysql.handle.query("UPDATE lager SET amount = ? WHERE id = ?", [newAmount, itemId], function(err3, res3) {
                                            
                                            if (err3) console.log("Error in Destroy Item Query 3: " + err3);
                                            else {
                                                player.notify("Du hast den Gegenstand weggeworfen.");
                                                mp.events.call("server:inventory:prepareMenu", player);
                                            }
                                        
                                    });

                                    }
                                } else {
                                    player.notify("Du kannst nicht weniger als 1 Wegwerfen.");
                                }
                            } else {
                                player.notify("So viel hast du nicht von diesem Gegenstand!");
                            }
                        });
                    } else {
                        player.notify("Du besitzt diesen Gegenstand nicht.");
                    }
                }
            });
        });
mit ON DUPLICATE KEY UPDATE itemId = VALUES(amount) + 1
Code:
  gm.mysql.handle.query("INSERT INTO lager (`charId`,`itemId`,`amount`) ON DUPLICATE KEY UPDATE itemId = VALUES(amount) + 1 SELECT charId,itemId,1  FROM user_items WHERE id = ? AND charId = ? ", [itemId, player.data.charId], function (err2,res2) {
habe ich es versucht dann pasiert leider garnichts mehr
03/21/2020 00:09 Shino#4
Was mein Vorposter glaube ich sagen wollte ist, dass du zuerst bei deiner Datenbank abfrägst ob dein Player das Item schon besitzt (also Select Befehl ausführen und dann schauen ob dir deine Datenbank dazu einen Eintrag zurück liefert. Wenn nein dann kannst du das mit deinem Insert into Befehl dann beheben). Sollte dir aber der Select Befehl einen Eintrag zurück geben, dann kannst du mit einem normalen Update Befehl (wie du auch weiter unten im Code schon verwendet hast) den Amount für dieses Item dann um 1 erhöhen.
Ebenfalls würde ich dir auch empfehlen dich mal ein bisschen mit Clean Code auseinander zu setzen. Solchen ewig verschachtelte If Abfragen sind schwer zu lesen bzw. nach zu vollziehen. Also am besten die ganzen Ifs auseinander ziehen (wenn z.B. output < 0 dann macht es wenig Sinn dann noch weiter zu machen in der Logik, weil der Spieler eh nichts machen kann. Auch ist die Abfrage if(res.length > 0) nicht nötig. Soviel ich weiß durchläuft die foreach bei einer Größe von 0 auch 0 mal).
03/25/2020 08:34 florian0#5
So eine Logik in zwei Queries zu trennen ist nicht immer eine gute Idee. Wenns keine parallelen Zugriffe auf die Datenbank gibt gehts noch. Aber sobalds parallel wird läufst du in Gefahr, dass das Ergebnis deines SELECT-Query "veraltet" ist bevor der INSERT oder UPDATE Query ausgeführt wird.

In einer ungünstigen Konstellation könnte dir sowas hier passieren:
Code:
T1 -> Thread 1
T2 -> Thread 2

T1 SELECT (ergebnis = kein eintrag vorhanden)
T2 SELECT (ergebnis = kein eintrag vorhanden)
T1 INSERT
T2 INSERT <- ERROR