ON DUPLICATE KEY

0

Chcę użyć ON DUPLICATE KEY, ponieważ czytałem że jeżeli istnieje podany rekord w INSERT INTO to wykonuje inną operację (u mnie UPDATE). Mam tak:

Kopiuj
INSERT INTO proba (`Nazwa`, `Ilosc`) VALUES('cos', '1') ON DUPLICATE KEY UPDATE `Ilosc` = '3'

Napisałem to do prób. Tabela wygląda tak:
id - int(11) auto increment
Nazwa - char(10)
Ilosc - tinyint(2)

Mimo takiego zastosowania za każdym razem dodaje to samo, zamiast zmienić Ilosc na 3.

Co robię źle ?

KO
  • Rejestracja:prawie 14 lat
  • Ostatnio:ponad 9 lat
  • Postów:39
0

Jak nazwa wskazuje on duplikate key działa wtedy, gdy klucz główny jest duplikowany. Zgaduję, że pole id jest kluczem głównym. Natomiast pole Ilosc nie jest kluczem, a jeżeli chcesz żeby było unikalne to może spróbuj unique.

0

Czyli działa to tak że sprawdza czy duplikowany jest klucz główny lub unikatowy i wtedy wykonuje UPDATE ?

A może być tak że Primary key to pole id, a unique to pole Ilosc ?

0

UNIQUE źle działa.

Patrząc na tabelę przedstawioną w 1 poście, chcę zrobić tak:

  • jeżeli istnieje już rekord o dokładnie takich samych polach jak dodawany (poza id i Ilosc) to ma zwiększyć pole Ilosc o 1
  • jeżeli nie istnieje to dodaje nowy rekord (id - kolejne z AI, Ilosc - 1).
Demonical Monk
  • Rejestracja:ponad 17 lat
  • Ostatnio:11 miesięcy
0

id - int(11) auto increment
Nazwa - char(10)
Ilosc - tinyint(2)

Używasz ON DUPLICATE, tak? Chcesz wywołać akcję, gdy klucz się powtarza, tak?

Podstawowo mamy dwa rekordy, dokładnie takie, które ty chciałbyś sklejać:

Kopiuj
+----+----------+-------+
| id | nazwa    | ilosc |
+----+----------+-------+
| 1  | Banan    | 2     |
| 2  | Banan    | 5     |
+----+----------+-------+

To teraz zagadka, względem jakiej kolumny trzeba pogrupować te rekordy?
Hint: Grupowanie według kolumny ma sens tylko jeśli wartości tej kolumny się powtarzają. Dużego wyboru nie masz. I... tak. To ta kolumna musi być kluczem.


Women were the reason I became a monk - and, ah, the reason I switched back...
edytowany 3x, ostatnio: Demonical Monk
0

Nie o to chodzi. Dajmy na to że chcę zapisywać id zalogowanego usera oraz ilość wejść na stronę. Przykładowo mamy tabelę:
rekord_id - int(11) auto increment
user_id - int(11)
count - int(11) - specjalnie dałem int(11)

Teraz ma działać to tak:

  • jeżeli nie ma jeszcze w tabeli tego usera to dodaję go, tak jak to robi:
Kopiuj
INSERT INTO tabela VALUES(NULL, 'jakis_numer', '1')
  • jeżeli jest to zmieniam wartość count na count+1;

Z poziomu php nie otrzymuję rekord_id (mysql zwiększa mi to automatycznie). Otrzymuję tylko user_id i tyle.

Demonical Monk
  • Rejestracja:ponad 17 lat
  • Ostatnio:11 miesięcy
0

Właśnie to co napisałem powyżej ilustruje ten przypadek...


Women were the reason I became a monk - and, ah, the reason I switched back...
0

No nie. Ty robisz tak że rekordy mają to samo "wnętrze" (czyli wszystko poza id i ilosc - w tym przypadku jest tylko nazwa, ale u mnie w bazie jest więcej pól).

Może jako lepszy przykład podam koszyk z polami:

id user_id nazwa kolor rozmiar ilosc (standardowo wstawia wartość 1)
1 1 rakietka czarny 100cm 2
2 1 piłka bialy 40cm 4
3 2 piłka czerwony 40cm 1
4 3 samochodzik niebieski 150cm 1

I teraz jest tak że pole id - jest typu auto increment, więc w zapytaniach wpisuję NULL lub po prostu nie podaję.

Chodzi o to że jeżeli mam:

Kopiuj
INSERT INTO koszyk (`user_id`, `nazwa`, `kolor`, `rozmiar`) VALUES('1', 'piłka', 'biały', '40cm')

to taki rekord istnieje i nie powinien go dodać tylko zrobić

Kopiuj
UPDATE ilosc = ilosc+1

Natomiast gdy moje zapytanie będzie wyglądać:

Kopiuj
INSERT INTO koszyk (`user_id`, `nazwa`, `kolor`, `rozmiar`) VALUES('1', 'piłka', 'niebieski', '40cm')

to doda nowy rekord (dałem tutaj kolor niebieski zamiast biały, dlatego powinien dodać rekord).

KO
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 13 lat
  • Postów:36
1

A masz zdefiniowane ograniczenie na unikalność pól userid + nazwa + kolor + rozmiar ?
Pewno nie, więc nie wystąpi zdarzenie zduplikowanego klucza.

[code]
mysql> create table koszyk(
-> id int primary key auto_increment,
-> user_id int,
-> nazwa varchar(50),
-> kolor varchar(50),
-> rozmiar varchar(50),
-> ilosc int default 1
-> );
Query OK, 0 rows affected (0.10 sec)

mysql> INSERT INTO koszyk (user_id, nazwa, kolor, rozmiar) VALUES('1', 'piłka', 'biały', '40cm');
Query OK, 1 row affected (0.07 sec)

mysql> INSERT INTO koszyk (user_id, nazwa, kolor, rozmiar) VALUES('1', 'piłka', 'biały', '40cm');
Query OK, 1 row affected (0.06 sec)

mysql> SELECT * FROM koszyk;
+----+---------+--------+--------+---------+-------+
| id | user_id | nazwa | kolor | rozmiar | ilosc |
+----+---------+--------+--------+---------+-------+
| 1 | 1 | piłka | biały | 40cm | 1 |
| 2 | 1 | piłka | biały | 40cm | 1 |
+----+---------+--------+--------+---------+-------+
2 rows in set (0.00 sec)

mysql> truncate table koszyk;
Query OK, 0 rows affected (0.07 sec)

mysql> alter table koszyk
-> add constraint unique( user_id, nazwa, kolor, rozmiar );
Query OK, 0 rows affected (0.17 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> INSERT INTO koszyk (user_id, nazwa, kolor, rozmiar) VALUES('1', 'piłka', 'biały', '40cm');
Query OK, 1 row affected (0.06 sec)

mysql> INSERT INTO koszyk (user_id, nazwa, kolor, rozmiar) VALUES('1', 'piłka', 'biały', '40cm');
ERROR 1062 (23000): Duplicate entry '1-piłka-biały-40cm' for key 'user_id'

mysql> select * from koszyk;
+----+---------+--------+--------+---------+-------+
| id | user_id | nazwa | kolor | rozmiar | ilosc |
+----+---------+--------+--------+---------+-------+
| 1 | 1 | piłka | biały | 40cm | 1 |
+----+---------+--------+--------+---------+-------+
1 row in set (0.00 sec)

mysql> INSERT INTO koszyk (user_id, nazwa, kolor, rozmiar) VALUES('1', 'piłka', 'biały', '40cm')
-> ON DUPLICATE KEY UPDATE ilosc = ilosc + 1;
Query OK, 2 rows affected (0.09 sec)

mysql> select * from koszyk;
+----+---------+--------+--------+---------+-------+
| id | user_id | nazwa | kolor | rozmiar | ilosc |
+----+---------+--------+--------+---------+-------+
| 1 | 1 | piłka | biały | 40cm | 2 |
+----+---------+--------+--------+---------+-------+
1 row in set (0.00 sec)

[/code]

1

Dzięki wielkie, już wiem gdzie tkwił błąd. Ja ustawiłem unique na próbę dla jednego pola, a powinno być dla wielu by to poprawnie działało.

0

Po licznych zapytaniach na forach i moich testach
i próbach nad zagadnieniem wsadzania nowych danych
do tablicy MYSQL (insert) wraz z update istniejących
rekordów przy pomocy jednego wywołania doszedłem do
następującego wzorca i konkluzji .
Proponuje zastosowanie składni :

1- sekcja INSERT INTO QSOS_AWARDS ( CALL , QSO_DATE , TIME_ON
, BAND , SUM_STRING )
2- sekcja SELECT T_CALL , T_QSO_DATE , T_ TIME_ON , T_BAND ,
T_SUM_STRING from T_QSOS_AWARDS
3-cia sekcja ON DULICATE UPDATE CALL= T_CALL ,
QSO_DATE = T_QSO_DATE ,
TIME_ON = T_ TIME_ON ,
BAND = T_BAND ,
SUM_STRING = T_SUM_STRING

Uwagi dodatkowe :

  1. Wszystkie pola są typu string u mnie - chociaż nie jest to wymagane
  2. Ilość pól we wszystkich sekcjach musi być identyczna - inaczej
    MYSQL zgłasza że Count fields in not this same .
  3. Jedno pole SUM_STRING u musi być kluczem typu PRIMARY -
    ale nie może to być pole AUTO_INCREMENT .
    Nie wystarcza by było to pole typu UNIQUE .
    U mnie było to pole które było po prostu sumą stringową pól CALL ,
    QSO_DATE , TIME_ON , BAND
    co zapewniało że to pole było unikalne i nie tworzyły się
    duplikaty .
    4 . Pole T_SUM_STRING powinno być co najmniej typu UNIQUE .
    Nie robiłem prób z polem typu PRIMARY ale sądzę że też
    by to zadziałało .
  4. W 3-ciej sekcji proszę zwrócić uwage na składnię. Wiele postów
    zaleca tutaj zastosowanie składni CALL= VALUES(T_CALL) lub
    CALL= VALUES(T_QSOS_AWARDS.T_CALL) .
    Nie jest to niestety poprawne - gdyż zawsze w tym
    przypadku otrzymywałem komunikat - Column T_CALL lub
    T_QSOS_AWARDS.T_CALL not found .
    Z praktyki mojej wynika że słowo VALUS () można tylko wykorzystwać
    jeśli w środku podamy konkretne wartości np VALUES(1,'ab' , 3)
    lub VALUES ( SUM_STRING + 'ab') - ale pola te mogą pochodzić tylko z
    1-szej sekcji .
  5. U mnie tablica T_QSOS_AWARDS to była tablica TEMPORARY , a więc
    przechowywana w pamięci ( co znacznie przyspieszyło) i
    stworzona poleceniem :
    CREATE TEMPORARY TABLE if not exists T_QSOS_AWARDS ( T_CALL ,
    T_QSO_DATE , T_ TIME_ON , T_BAND , T_SUM_STRING)
    Oczywiscie w liście pól były jeszcze podane typy pól zgodnie
    ze składnią MYSQL .
  6. Dla tablicy T_QSOS_AWARDS był stworzony dodatkowo index typu
    UNIQUE poleceniem
    ADOCommCreaInsert.CommandText :='CREATE UNIQUE INDEX '
    + 'IDX_T_SUM_STRING'
    + ' ON TEMP_QSOS_AWARDS
    ('T_SUM_STRING' )';
    ADOCommCreaInsert.Execute;
    8 . Tablica QSOS_AWARDS może zawierać jeszcze inne pola -
    ale wyżej musimy podać tylko te pola które insertujemy
    lub podajemy upadate . Ta liczba tych pól musi być
    ta sama .
    9 . Można zastosować jeszcze pole Identyfikator np ID_QSO indeksowane -
    który można ustawić na AUTO_INCREMENT .
    Takiemu polu nigdy nie nadajemy wartości .
    Pozdrawiam Wszystkich - SP9AUV
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)