Kleine Frage zu SQL

Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Hi,


    ich habe eine kleine Frage zu (My)SQL.
    Wenn ich etwas in eine Datenbank inserten lasse (Bsp: INSERT INTO `Test` (`Name`, `Level`) VALUES (`Deagle`, `6`) ) und es in dieser Tabelle "Test" eine AUTO_INCREMENT-Spalte (Primary Key(XXX)) gibt (Sagen wir ID).
    Dies dann lösche (DELETE * FROM `Test` WHERE `Name` = 'Deagle'). Dann etwas neues einfüge, bekommt das neue dann die AUTO_INCREMENT-ID von "Deagle"?


    lg
    Deagle


    P.S.: Ich weiß, das ist etwas unverständlich. In der Theorie möchte ich nur wissen, ob die AUTO_INCREMENT nur hoch zählt, oder sich auch "ersetzen" lässt.

  • Nein. Wenn dein letzter Eintrag z.B. ID 6 hat, du diesen löscht und dann einen neuen Einfügst, bekommt dieser automatisch ID 7.
    Du könntest den Key-Operator beim Löschen eines Eintrags wieder -1 setzen, was aber dumm wäre, weil du ja nicht weißt, ob du wirklich den letzten Eintrag löschst ;)


    Mein CS:GO Server: 62.75.168.39:27016


    Ich bin so hungrig, dass ich vor lauter Durst nicht weiß, was ich rauchen soll - so müde bin ich!
    Freedom is just another word for 'Nothing left to lose'

  • Keine Ahnung, dafür müsstest du mir mal etwas genauer erklären, was du vor hast, denn aus deiner Beschreibung werde ich diesbezüglich nicht schlau.


    Mein CS:GO Server: 62.75.168.39:27016


    Ich bin so hungrig, dass ich vor lauter Durst nicht weiß, was ich rauchen soll - so müde bin ich!
    Freedom is just another word for 'Nothing left to lose'

  • Gibt es dort eine andere Möglichkeit? Z.b. wenn ID und NAME gleich sind (Aber dafür kein Primary Key)?


    Klar gibt es da eine Möglichkeit.
    Du nimmst ein Array, und setzt den Index der ID jeweils auf true wenn die ID in der Datenbank existiert. Wird ein Wert gelöscht, dann setzt du den Index wieder auf false.
    Beim Hinzufügen loopst du durch das Array und schaust welcher Index zuerst false ist (finden des kleinsten Index).


    Auto increment muss dafür natürlich entfernt werden. Den Primary key kannst du bestehen lassen.


    Beispiel mit Häusern:
    new bool:InDB[MAX_HAUS];


    InDB[id] = true; //bzw false beim löschen


    Finden des Index zum hinzufügen
    for(new i=0;i<MAX_HAUS;i++)
    {
    if(InDB[i]) continue; //Index existiert, weiter.
    id=i;
    break;
    }
    //dann hier das Haus erstellen und InDB von id auf true setzen.



    Edit:
    DJ Deagle: Mache ich heute Abend, bin nicht zu Hause.

    3HZXdYd.png

    Einmal editiert, zuletzt von Jeffry ()

  • Du nimmst ein Array, und setzt den Index der ID jeweils auf true wenn die ID in der Datenbank existiert. Wird ein Wert gelöscht, dann setzt du den Index wieder auf false.
    Beim Hinzufügen loopst du durch das Array und schaust welcher Index zuerst false ist (finden des kleinsten Index).


    Ich versteh' grad nur Bahnhof. Ich habe folgendes gebastelt:
    new string[256],str[256],seller,model,reward;
    mysql_query("SELECT * FROM `Ordereddealercars`");
    mysql_store_result();
    while(mysql_fetch_row_format(string))
    {
    sscanf(string,"p<|>{i}ddd",seller,model,reward);
    format(str,sizeof str,"%s{00FF00}%s {FFFFFF}für {00FF00}%s{FFFFFF}€\n",str,PlayerVehicle[model-400],inspoints(reward));
    }
    mysql_free_result();
    if(strlen(str) > 0) {
    ShowPlayerDialog(playerid,DLG_TRUCKER_CARIMPORT,DIALOG_STYLE_LIST,"Fahrzeugbestellungen",str,"Auswählen","Abbrechen");
    } else {
    SendClientMessage(playerid,COLOR_LIGHTRED,"Es gibt zur Zeit keine Fahrzeugbestellungen!");
    }


    //Wenn auf ein Item geklickt wurd:
    case DLG_TRUCKER_CARIMPORT:
    {
    if(response) {
    switch(listitem) {
    case 0: {/*JTrailerInfo[MAX_VEHICLES][JobTrailer];
    Jobtrailer[MAX_PLAYERS]*/
    new q[256],seller,model,reward,Float:lPos[3],Float:zang;
    mysql_query("SELECT `Seller`, `Model`, `Reward` FROM `Ordereddealercars` WHERE `ID` = '0'");
    mysql_store_result();
    while(mysql_fetch_row_format(q)) {
    sscanf(q,"p<|>{i}ddd",seller,model,reward);
    }
    GetPlayerPos(playerid,lPos[0],lPos[1],lPos[2]);
    GetVehicleZAngle(GetPlayerVehicleID(playerid),zang);
    Jobtrailer[playerid] = CreateVehicle(591,lPos[0]+5,lPos[1],lPos[2],zang,random(128),random(128),-1);
    JTrailerInfo[Jobtrailer[playerid]][jSeller] = seller;
    JTrailerInfo[Jobtrailer[playerid]][jModel] = model;
    JTrailerInfo[Jobtrailer[playerid]][jReward] = reward;
    AttachTrailerToVehicle(Jobtrailer[playerid],GetPlayerVehicleID(playerid));
    inJob[playerid] = 1;
    TruckerjobCP[playerid] = 120;
    SetPlayerCheckpoint(playerid,AHInfo[seller][zPosX],AHInfo[seller][zPosY],AHInfo[seller][zPosZ],7);
    SendClientMessage(playerid,COLOR_WHITE,"");
    SendClientMessage(playerid,COLOR_WHITE,"Bitte fahre zum Autohaus und lade das Fahrzeug ab!");
    mysql_query("DELETE * FROM `Ordereddealercars` WHERE `ID` = '0'");
    }
    }
    }
    }
    Doch ich merke, dass das failen wird.


    Kannst du es Schritt für Schritt erklären?

  • Auf dein Beispiel Code hier bezogen brauchst du den ganzen Aufwand gar nicht, da du mit hart programmierten IDs arbeitest (du hast die 0 direkt ins query geschrieben).


    Wenn du es über einen solchen switch machst, und die ID immer hart in das query schreibst, dann musst du nichts weiter machen, als das Auto Increment entfernen.


    Falls du die IDs doch über Platzhalter (%d) einfügen willst, dann aktualisiere bitte den Code, da es sonst nicht geht dir das genau zu erklären.

  • Wenn du es über einen solchen switch machst, und die ID immer hart in das query schreibst, dann musst du nichts weiter machen, als das Auto Increment entfernen.


    Bezogen auf, das wird nicht klappen ist folgender Code:
    mysql_query("SELECT * FROM `Ordereddealercars`");
    mysql_store_result();
    new r=mysql_num_rows();
    mysql_free_result();
    format(q,sizeof q,"INSERT INTO `Ordereddealercars` (`ID`, `Seller`, `Model`, `Reward`) VALUES ('%d', '%d', '%d', '%d')",r,i,veh,lk);
    mysql_query(q);
    Da wird eingeschrieben.. Wenn du verstehst was ich meine (mit Das wird ned klappen).

  • Naja, der Code macht ja auch keinen Sinn. Der zählt ja nur wie viele Zeilen du hast und erstellt dann eine Zeile mit ID = Anzahl der Zeilen. Das gibt für mich keinen Sinn.


    Wenn du den SELECT weg machst, und anstelle von r in den Parametern von format eine 0 setzt (harte 0 wie bei dem anderen Code), dann sollte es klappen.


    Allerdings habe ich den Hintergrund deines Systems noch nicht verstanden, da dein erster Code sich irgendwie mit dem zweiten Code widerspricht.

  • Allerdings habe ich den Hintergrund deines Systems noch nicht verstanden, da dein erster Code sich irgendwie mit dem zweiten Code widerspricht.


    Also. Mein Autohaussystem. Sobald man ein Fahrzeug bestellt, soll dieses in die Datenbank eingetragen werden.
    Trucker sollen dann Einsicht in diese Einträge haben (InGame) und aus dieser Einsicht wählen können (List-Dialog).

  • Sobald man ein Fahrzeug bestellt, soll dieses in die Datenbank eingetragen werden.
    Trucker sollen dann Einsicht in diese Einträge haben (InGame) und aus dieser Einsicht wählen können (List-Dialog).


    Dafür ist es aber egal, ob der Index AUTO INCREMENT hat oder nicht. Wenn du die Datenbank-ID in eine Variable speicherst, auf die der Index verweist
    db_ID[listitem]
    dann funktioniert es auch mit einem AUTO INCREMENT.


    Eine wesentlich einfachere Möglichkeit wäre es, das ganze über eine Datei zu lösen. Dann brauchst du die neuen Fahrzeuge nur mit io_append hinten anfügen und die erledigten Fahrzeuge löschst du aus der Datei, die anderen Zeilen rücken logischerweise nach, wenn du eine Zeile löschst. Somit hast du das Problem gar nicht mehr.



    Falls du trotzdem das System gerne mit MySQL machen willst, dann sieht das so aus:
    new string[256],str[256],seller,model,reward,id,i;
    mysql_query("SELECT * FROM `Ordereddealercars`");
    mysql_store_result();
    while(mysql_fetch_row_format(string))
    {
    sscanf(string,"p<|>iddd",id,seller,model,reward);
    db_ID[i] = id;
    format(str,sizeof str,"%s{00FF00}%s {FFFFFF}für {00FF00}%s{FFFFFF}€\n",str,PlayerVehicle[model-400],inspoints(reward));
    i++;
    }
    mysql_free_result();
    if(strlen(str) > 0)
    {
    ShowPlayerDialog(playerid,DLG_TRUCKER_CARIMPORT,DIALOG_STYLE_LIST,"Fahrzeugbestellungen",str,"Auswählen","Abbrechen");
    }
    else
    {
    SendClientMessage(playerid,COLOR_LIGHTRED,"Es gibt zur Zeit keine Fahrzeugbestellungen!");
    }



    Und beim Select:
    format(query, sizeof(query), "SELECT `Seller`, `Model`, `Reward` FROM `Ordereddealercars` WHERE `ID` = '%d'", db_ID[listitem]);
    mysql_query(query);


    ebenso beim löschen des Datensatzes:
    format(query, sizeof(query), "DELETE * FROM `Ordereddealercars` WHERE `ID` = '%d'", db_ID[listitem]);
    mysql_query(query);



    Nicht vergessen die
    new db_ID[MAX_FAHRZEUGE];
    zu erstellen.


    Außerdem solltest du, sobald ein Spieler ein Fahrzeug ausgewählt hat, für alle die den Dialog mit den ganzen Autos offen haben, den Dialog neu anzeigen, da es sonst vorkommen kann, dass zwei Spieler den gleichen Index auswählen. Oder du fängst das ab, wenn der Datensatz nicht mehr existiert, dass dann eine Fehlermeldung kommt.

    3HZXdYd.png

    Einmal editiert, zuletzt von Jeffry ()


  • Woher weis db_ID denn, dass es [i] sein muss? o.o
    Ich verstehe zwar, wie ich es machen soll, aber einiges check ich auch ned.

  • new string[256],str[256],seller,model,reward,id,i; //Zu diesem Zeitpunkt ist i = 0
    mysql_query("SELECT * FROM `Ordereddealercars`");
    mysql_store_result();
    while(mysql_fetch_row_format(string))
    {
    sscanf(string,"p<|>iddd",id,seller,model,reward);
    db_ID[i] = id; //Hier wäre dann db_ID[0] = id (aus der DB), beim nächsten Durchlauf dann db_ID[1], etc...
    format(str,sizeof str,"%s{00FF00}%s {FFFFFF}für {00FF00}%s{FFFFFF}€\n",str,PlayerVehicle[model-400],inspoints(reward));
    i++; //hier wird i = 0 zu i = 1, dann i = 1 zu 1 = 2 [hatte im Code zuvor gefehlt *shame*]
    }
    mysql_free_result();
    if(strlen(str) > 0)
    {
    ShowPlayerDialog(playerid,DLG_TRUCKER_CARIMPORT,DIALOG_STYLE_LIST,"Fahrzeugbestellungen",str,"Auswählen","Abbrechen");
    }
    else
    {
    SendClientMessage(playerid,COLOR_LIGHTRED,"Es gibt zur Zeit keine Fahrzeugbestellungen!");
    }


    Jetzt sollte es klarer sein.

  • Jetzt sollte es klarer sein.


    Ok. Nun klappt alles wunderbar. Leider werden nun ab der markierten Zeile keine Sachen mehr ausgeführt (SendClientMessage usw):
    case DLG_TRUCKER_CARIMPORT:
    {
    if(response) {
    new q[256],seller,model,reward,Float:lPos[3],Float:zang,query[256];
    format(query,sizeof query,"SELECT `Seller`, `Model`, `Reward` FROM `Ordereddealercars` WHERE `ID` = '%d'", db_ID[listitem]);
    mysql_query(query);
    mysql_store_result();
    while(mysql_fetch_row_format(q)) {
    sscanf(q,"p<|>{i}ddd",seller,model,reward);
    }
    mysql_free_result();
    GetPlayerPos(playerid,lPos[0],lPos[1],lPos[2]);
    GetVehicleZAngle(GetPlayerVehicleID(playerid),zang);
    Jobtrailer[playerid] = CreateVehicle(591,lPos[0],lPos[1],lPos[2]+1000,zang,random(128),random(128),-1);
    JTrailerInfo[Jobtrailer[playerid]][jSeller] = seller;
    JTrailerInfo[Jobtrailer[playerid]][jModel] = model;
    JTrailerInfo[Jobtrailer[playerid]][jReward] = reward;
    SetTimerEx("AttachTrailerToTruck",750,0,"ddd",playerid,Jobtrailer[playerid],GetPlayerVehicleID(playerid));
    TogglePlayerControllable(playerid,false);
    GetVehicleParamsEx(GetPlayerVehicleID(playerid),engine,lights,alarm,doors,bonnet,boot,objective);
    SetVehicleParamsEx(GetPlayerVehicleID(playerid),VEHICLE_PARAMS_ON,lights,alarm,doors,bonnet,boot,objective);
    Motor[GetPlayerVehicleID(playerid)] = true;
    //Ab hier geht nix mehr.
    inJob[playerid] = 1;
    TruckerjobCP[playerid] = 120;
    SetPlayerCheckpoint(playerid,AHInfo[seller][zPosX],AHInfo[seller][zPosY],AHInfo[seller][zPosZ],7);
    printf("%f | %f | %f",AHInfo[seller][zPosX],AHInfo[seller][zPosY],AHInfo[seller][zPosZ]);
    SendClientMessage(playerid,COLOR_WHITE,"");
    SendClientMessage(playerid,COLOR_WHITE,"Bitte fahre zum Autohaus und lade das Fahrzeug ab!");
    format(query,sizeof query,"DELETE * FROM `Ordereddealercars` WHERE `ID` = '%d'", db_ID[listitem]);
    mysql_query(query);
    }
    }
    Warum?

  • SetVehicleParamsEx(GetPlayerVehicleID(playerid),VEHICLE_PARAMS_ON,lights,alarm,doors,bonnet,boot,objective);
    printf("VehicleID: %d", GetPlayerVehicleID(playerid));
    Motor[GetPlayerVehicleID(playerid)] = true;
    //Ab hier geht nix mehr.
    printf("playerid: %d", playerid);
    inJob[playerid] = 1;
    print("inJob gesetzt");
    TruckerjobCP[playerid] = 120;
    print("TruckerjobCP gesetzt");
    SetPlayerCheckpoint(playerid,AHInfo[seller][zPosX],AHInfo[seller][zPosY],AHInfo[seller][zPosZ],7);


    Debugge es mal so. Was wird geprintet?
    (Der Compiler passt, das ist ja nur die Kopfzeile.)

  • Debugge es mal so. Was wird geprintet?


    Habe es so debuggt:
    SetVehicleParamsEx(GetPlayerVehicleID(playerid),VEHICLE_PARAMS_ON,lights,alarm,doors,bonnet,boot,objective);
    printf("VehicleID: %d", GetPlayerVehicleID(playerid));
    Motor[GetPlayerVehicleID(playerid)] = true;
    //Ab hier geht nix mehr.
    printf("playerid: %d", playerid);
    inJob[playerid] = 1;
    print("inJob gesetzt");
    TruckerjobCP[playerid] = 120;
    print("TruckerjobCP gesetzt");
    SetPlayerCheckpoint(playerid,AHInfo[seller][zPosX],AHInfo[seller][zPosY],AHInfo[seller][zPosZ],7);
    print("Checkpoint gesetzt.");
    printf("Checkpointkoordinaten: %f | %f | %f",AHInfo[seller][zPosX],AHInfo[seller][zPosY],AHInfo[seller][zPosZ]);
    SendClientMessage(playerid,COLOR_WHITE,"");
    Output:

    Code
    [17:59:16] VehicleID: 1
    [17:59:16] playerid: 2
    [17:59:16] inJob gesetzt
    [17:59:16] TruckerjobCP gesetzt
  • Setz unter den Tuckerjob print mal ein
    printf("X: %f - Y: %f - Z: %f", AHInfo[seller][zPosX],AHInfo[seller][zPosY],AHInfo[seller][zPosZ]);


    Mein CS:GO Server: 62.75.168.39:27016


    Ich bin so hungrig, dass ich vor lauter Durst nicht weiß, was ich rauchen soll - so müde bin ich!
    Freedom is just another word for 'Nothing left to lose'

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen