Skocz do zawartości

Witamy w Nieoficjalnym polskim support'cie AMX Mod X

Witamy w Nieoficjalnym polskim support'cie AMX Mod X, jak w większości społeczności internetowych musisz się zarejestrować aby móc odpowiadać lub zakładać nowe tematy, ale nie bój się to jest prosty proces w którym wymagamy minimalnych informacji.
  • Rozpoczynaj nowe tematy i odpowiedaj na inne
  • Zapisz się do tematów i for, aby otrzymywać automatyczne uaktualnienia
  • Dodawaj wydarzenia do kalendarza społecznościowego
  • Stwórz swój własny profil i zdobywaj nowych znajomych
  • Zdobywaj nowe doświadczenia

Dołączona grafika Dołączona grafika

Guest Message by DevFuse
 

Zdjęcie

Podbijanie ID w mysqlu przy insertowaniu duplikatów


  • Nie możesz napisać tematu
  • Zaloguj się, aby dodać odpowiedź
12 odpowiedzi w tym temacie

#1 Robiin

    Godlike

  • Support Team

Reputacja: 1 111
Super Hero

  • Postów:2 066
  • Imię:Robert
  • Lokalizacja:Wrocław
Offline

Napisano 18.05.2024 17:07

    new Handle:insert_query = SQL_PrepareQuery(sql_connection,
        "INSERT INTO `missions` (`uid`, `name`, `desc`, `goal`) VALUES ('%s', '%s', '%s', '%i') \
        ON DUPLICATE KEY UPDATE `desc`='%s', `name`='%s', `goal`='%i';",
        uid, name, desc, goal, name, desc, goal);

Powyższe zapytanie robi jedną niefajną rzecz: mimo, że nie dodaje rekordu jeśli dana misja istnieje, to podbija id (to z AUTO_INCREMENT). Doczytałem, że to nie jest bug tylko celowe działanie, które ma coś tam zabezpieczyć. No ale nie widzi mi się robić osobnego zapytania (a w dodatku threaded), żeby sprawdzić czy dana misja jest już dodana.

Zapytanie ma na celu dodać rekord, jeśli taki nie istnieje, i zaktualizować go, jeśli coś się zmieniło.

Jakieś pomysły?


  • +
  • -
  • 0

Nie dołączam do żadnej sieci, nie pomagam z tworzeniem paczek, nie napisze pluginów za zero.


#2 dasiek

    Nie wiem, nie znam się, nie orientuję się, zarobiony jestem.

  • Junior Admin

Reputacja: 2 079
Godlike

  • Postów:5 710
  • Imię:Adaś
  • Lokalizacja:No teraz trochę dalej od WWy
Offline

Napisano 18.05.2024 19:48

1) zamknąć całą logikę ze sprwadzeniem czy misja istnieje czy nie w procedurze sql i ją wykonywać. 

2) przeprojektować bazę żeby nie korzystać z AUTO_INCREMENT.


  • +
  • -
  • 0

#3 Robiin

    Godlike

  • Autor tematu
  • Support Team

Reputacja: 1 111
Super Hero

  • Postów:2 066
  • Imię:Robert
  • Lokalizacja:Wrocław
Offline

Napisano 18.05.2024 21:42

A może w sumie nonthreaded update? Przecież mogę robic update nawet jeśli rekord nie istnieje, wszystko przed zapytaniem z górnego postu? A potem tylko INSERT IGNORE

 

@edit No chyba, że by wciąż podbijało id...


Użytkownik Robiin edytował ten post 18.05.2024 22:25

  • +
  • -
  • 0

Nie dołączam do żadnej sieci, nie pomagam z tworzeniem paczek, nie napisze pluginów za zero.


#4 Engi

    [EKSiD] playaz44

  • Power User

Reputacja: 316
Wszechpomocny

  • Postów:1 073
  • GG:
  • Imię:Seba
  • Lokalizacja:Praga
Offline

Napisano 19.05.2024 18:06

A dlaczego nie zrobisz tak:
 

INSERT INTO `missions` (`uid`, `name`, `desc`, `goal`) VALUES ('%s', '%s', '%s', '%i') \
        ON DUPLICATE KEY UPDATE `uid`=`uid`, `desc`='%s', `name`='%s', `goal`='%i'; 

btw: 

 

Nazwa 'desc' jest zastrzeżonym słowem kluczowym MySQL.

 


  • +
  • -
  • 0
Użytkowniku! Zanim napiszesz wiadomość wiedz, że:

W odpowiedzi na ten status, przejrzałem kilka ostatnich Twoich postów i dodałem Ci kolejne 3 punkty ostrzeżeń. Mam nadzieję, że pomogłem.

1:0 dla Benia :D
Nie pomagam za darmo na pw.

#5 DarkGL

    Nie oddam ciasteczka !

  • Administrator

Reputacja: 6 559
Godlike

  • Postów:11 999
  • GG:
  • Steam:steam
  • Imię:Rafał
  • Lokalizacja:Warszawa
Offline

Napisano 19.05.2024 19:25

Jednej rzeczy nie rozumiem, co Ci to zmienia że auto_increment jest podbijane ?


  • +
  • -
  • 0

#6 Robiin

    Godlike

  • Autor tematu
  • Support Team

Reputacja: 1 111
Super Hero

  • Postów:2 066
  • Imię:Robert
  • Lokalizacja:Wrocław
Offline

Napisano 19.05.2024 19:47

Technicznie rzecz biorąc to nic. Zanim zabraknie mi id, to minie dużo czasu. No ale wolałbym, żeby wszystko szło ładnie, a w dodatku czegoś się nauczę.

 

Na ten moment zrobiłem dwa zapytania. Pierwsze z update, drugie takie:

INSERT INTO `missions` (`uid`, `name`, `desc`, `goal`)
SELECT 'jakiesuid', 'jakasnazwa', 'jakisopis', 1
WHERE NOT EXISTS (
    SELECT 1
    FROM `missions`
    WHERE `uid` = 'jakiesuid'
);


btw: 

Cytat

 

Nazwa 'desc' jest zastrzeżonym słowem kluczowym MySQL.

 

https://stackoverflo...me-as-sql-types

 

 

You can use reserved keywords as identifiers as well, but you have to quote them.

 


  • +
  • -
  • 0

Nie dołączam do żadnej sieci, nie pomagam z tworzeniem paczek, nie napisze pluginów za zero.


#7 DarkGL

    Nie oddam ciasteczka !

  • Administrator

Reputacja: 6 559
Godlike

  • Postów:11 999
  • GG:
  • Steam:steam
  • Imię:Rafał
  • Lokalizacja:Warszawa
Offline

Napisano 19.05.2024 20:00

BEGIN;


IF EXISTS (SELECT 1 FROM missions WHERE uid = '%s') THEN
    UPDATE missions SET `desc` = '%s', `name` = '%s', `goal` = '%i' WHERE uid = '%s';
ELSE
    INSERT INTO missions (`uid`, `name`, `desc`, `goal`) VALUES ('%s', '%s', '%s', '%i');
END IF;

COMMIT;

 

tylko nie wiem czy mysql w amxx to wspiera

 


  • +
  • -
  • 0

#8 Robiin

    Godlike

  • Autor tematu
  • Support Team

Reputacja: 1 111
Super Hero

  • Postów:2 066
  • Imię:Robert
  • Lokalizacja:Wrocław
Offline

Napisano 20.05.2024 09:55

Nie wspiera, albo sam mysql ma problem z syntaxem ifów. Wymyśliłem coś takiego:

START TRANSACTION;

UPDATE `missions`
SET `name` = '%s', `desc` = '%s', `goal` = %i
WHERE `uid` = '%s';

SET @row_count = ROW_COUNT();

INSERT INTO `missions` (`uid`, `name`, `desc`, `goal`)
SELECT '%s', '%s', '%s', %i
WHERE NOT EXISTS (
    SELECT 1
    FROM `missions`
    WHERE `uid` = '%s'
    AND @row_count = 0
);

COMMIT;

Problem tylko w tym, że "Commands out of sync; you can't run this command now"


Użytkownik Robiin edytował ten post 20.05.2024 10:29

  • +
  • -
  • 0

Nie dołączam do żadnej sieci, nie pomagam z tworzeniem paczek, nie napisze pluginów za zero.


#9 DarkGL

    Nie oddam ciasteczka !

  • Administrator

Reputacja: 6 559
Godlike

  • Postów:11 999
  • GG:
  • Steam:steam
  • Imię:Rafał
  • Lokalizacja:Warszawa
Offline

Napisano 20.05.2024 11:57

FROM w drugim select chyba brakuje


  • +
  • -
  • 0

#10 Robiin

    Godlike

  • Autor tematu
  • Support Team

Reputacja: 1 111
Super Hero

  • Postów:2 066
  • Imię:Robert
  • Lokalizacja:Wrocław
Offline

Napisano 20.05.2024 19:57

Jest git, w drugim właśnie jest from. A pierwszy (ten z insert) to tylko wymienione wartości do wprowadzenia


  • +
  • -
  • 0

Nie dołączam do żadnej sieci, nie pomagam z tworzeniem paczek, nie napisze pluginów za zero.


#11 dasiek

    Nie wiem, nie znam się, nie orientuję się, zarobiony jestem.

  • Junior Admin

Reputacja: 2 079
Godlike

  • Postów:5 710
  • Imię:Adaś
  • Lokalizacja:No teraz trochę dalej od WWy
Offline

Napisano 21.05.2024 08:43

Sobie machnąłem taką tabele na testowym serwerze

CREATE TABLE `missions` (`uid` INT UNSIGNED NOT NULL AUTO_INCREMENT , `desc` VARCHAR(32) NOT NULL , `goal` INT(1) UNSIGNED NOT NULL , `name` VARCHAR(32) NOT NULL , PRIMARY KEY (`uid`))

 Dodałem do niego dwa rekordy
 

INSERT INTO `missions` (`uid`, `desc`, `goal`, `name`) VALUES (NULL, 'ASDF', '1', 'ASDF');
INSERT INTO `missions` (`uid`, `desc`, `goal`, `name`) VALUES (NULL, 'DUPA', '1', 'DUPA');

Sprawdziłem, jaki jest następny Następny Autoincrement 

SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'XYZ' AND TABLE_NAME = 'missions';

Zwróciło mnie "3" - więcj jest ok.

Następnie podpytałem trochę ejaja co tu się dzieje (skoro ma zabrać moją pracę, to musi się znać na robocie, a ze jest darmowy i ostatnio zrobił progress to czemu nie) i mi zasugerował albo ON DUPLICATE KEY, albo procedurę. Na pytanie jak zapobiec aktualizacji autoincrement powiedział tak

 

Jeśli chcesz uniknąć aktualizacji kolumny id oznaczonej jako AUTO_INCREMENT podczas użycia INSERT ... ON DUPLICATE KEY UPDATE, musisz upewnić się, że ta kolumna nie jest uwzględniona w sekcji UPDATE. W sekcji UPDATE powinny być tylko te kolumny, które chcesz zaktualizować.

 

I dał mi przykład. zmodyfikowałem go pod moje testowe tabele.

INSERT INTO missions (uid, `desc`, `goal`, `name`) VALUES (2, 'example', 1, 'value1') ON DUPLICATE KEY UPDATE `desc` = VALUES(`desc`), `name` = VALUES(`name`);

O dziwo, rekordy zostały zaktualizowane, a `SELECT AUTOINCREMENT` który juz wcześniej zrobiłem nadal zwrócił mi 3.

Więc dodałem następne dwa rekordy, mam pięknie ajdiki 1,2,3,4, więc coś mnie tu nie pasuje  :krecka_dostal:

 

Swoją drogą, postarał się nasz ejaj, bardzo dużo treści wygenerował, łapcie link: https://chatgpt.com/...a1-0cae3b147fca

 


dasiek (21.05.2024 09:25):

A moze to być kwestia tego, że na testówce mam MariaDB:10.3.22, a nie mysql...


  • +
  • -
  • 0

#12 Engi

    [EKSiD] playaz44

  • Power User

Reputacja: 316
Wszechpomocny

  • Postów:1 073
  • GG:
  • Imię:Seba
  • Lokalizacja:Praga
Offline

Napisano 21.05.2024 10:04

Sobie machnąłem taką tabele na testowym serwerze

CREATE TABLE `missions` (`uid` INT UNSIGNED NOT NULL AUTO_INCREMENT , `desc` VARCHAR(32) NOT NULL , `goal` INT(1) UNSIGNED NOT NULL , `name` VARCHAR(32) NOT NULL , PRIMARY KEY (`uid`))

 Dodałem do niego dwa rekordy
 

INSERT INTO `missions` (`uid`, `desc`, `goal`, `name`) VALUES (NULL, 'ASDF', '1', 'ASDF');
INSERT INTO `missions` (`uid`, `desc`, `goal`, `name`) VALUES (NULL, 'd*pa', '1', 'd*pa');

Sprawdziłem, jaki jest następny Następny Autoincrement 

SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'XYZ' AND TABLE_NAME = 'missions';

Zwróciło mnie "3" - więcj jest ok.

Następnie podpytałem trochę ejaja co tu się dzieje (skoro ma zabrać moją pracę, to musi się znać na robocie, a ze jest darmowy i ostatnio zrobił progress to czemu nie) i mi zasugerował albo ON DUPLICATE KEY, albo procedurę. Na pytanie jak zapobiec aktualizacji autoincrement powiedział tak

 

Jeśli chcesz uniknąć aktualizacji kolumny id oznaczonej jako AUTO_INCREMENT podczas użycia INSERT ... ON DUPLICATE KEY UPDATE, musisz upewnić się, że ta kolumna nie jest uwzględniona w sekcji UPDATE. W sekcji UPDATE powinny być tylko te kolumny, które chcesz zaktualizować.

 

I dał mi przykład. zmodyfikowałem go pod moje testowe tabele.

INSERT INTO missions (uid, `desc`, `goal`, `name`) VALUES (2, 'example', 1, 'value1') ON DUPLICATE KEY UPDATE `desc` = VALUES(`desc`), `name` = VALUES(`name`);

O dziwo, rekordy zostały zaktualizowane, a `SELECT AUTOINCREMENT` który juz wcześniej zrobiłem nadal zwrócił mi 3.

Więc dodałem następne dwa rekordy, mam pięknie ajdiki 1,2,3,4, więc coś mnie tu nie pasuje  :krecka_dostal:

 

Swoją drogą, postarał się nasz ejaj, bardzo dużo treści wygenerował, łapcie link: https://chatgpt.com/...a1-0cae3b147fca

 

Dałeś się wkręcić tak samo jak ja, uid nie jest auto increment ale random stringiem, on ma osobno id jako auto increment, czyli id, uid, desc, goal, name. Pierwszy sql z pierwszego posta działa jeżeli wrzucisz uid jako unique ale dalej podnosi auto increment bo to innodb, na myisam nie podnosi.


dasiek (21.05.2024 11:50):

LOL


  • +
  • -
  • 1
Użytkowniku! Zanim napiszesz wiadomość wiedz, że:

W odpowiedzi na ten status, przejrzałem kilka ostatnich Twoich postów i dodałem Ci kolejne 3 punkty ostrzeżeń. Mam nadzieję, że pomogłem.

1:0 dla Benia :D
Nie pomagam za darmo na pw.

#13 Robiin

    Godlike

  • Autor tematu
  • Support Team

Reputacja: 1 111
Super Hero

  • Postów:2 066
  • Imię:Robert
  • Lokalizacja:Wrocław
Offline

Napisano 21.05.2024 15:00

Tak, to prawda. Nie doprecyzowałem, że uid to nie jest to od auto incrementa, tylko mój randomowy string. W każdym razie zrobiłem tak i już tak zostanie:

SQL_PrepareQuery(sql_connection,
        "UPDATE `missions` SET `desc`='%s', `name`='%s', `goal`='%i' WHERE `uid` = '%s';",
        desc, name, goal, uid);

A potem

SQL_PrepareQuery(sql_connection,
        "INSERT INTO `missions` (`uid`, `name`, `desc`, `goal`) \
        SELECT '%s', '%s', '%s', %i \
        WHERE NOT EXISTS ( \
            SELECT 1 \
            FROM `missions` \
            WHERE `uid` = '%s' \
        );",
        uid, name, desc, goal,
        uid);


Swoją drogą, postarał się nasz ejaj, bardzo dużo treści wygenerował, łapcie link: https://chatgpt.com/...a1-0cae3b147fca

Musiałeś podziękować za informację, żeby uniknąć śmierci w 2050 jak już wyjdą pierwsze wersje terminatorów? Mądrze...


dasiek (21.05.2024 15:26):

Dziękuję za pomoc ejaj, dzień dobry mówię zawsze... ja dobry chłopak jestem...


  • +
  • -
  • 0

Nie dołączam do żadnej sieci, nie pomagam z tworzeniem paczek, nie napisze pluginów za zero.





Użytkownicy przeglądający ten temat: 1

0 użytkowników, 1 gości, 0 anonimowych