MySQL Wstaw gdzie zapytanie

121

Co jest nie tak z tym zapytaniem:

INSERT INTO Users( weight, desiredWeight ) VALUES ( 160, 145 ) WHERE id = 1;

Działa bez WHEREklauzuli. Wyglądało na to, że zapomniałem swojego kodu SQL

Taryn
źródło

Odpowiedzi:

237

Składnia MySQL INSERT nie obsługuje klauzuli WHERE, więc zapytanie w obecnej postaci zakończy się niepowodzeniem. Zakładając, że Twoja idkolumna jest unikatowa lub kluczem podstawowym:

Jeśli próbujesz wstawić nowy wiersz o identyfikatorze 1, powinieneś użyć:

INSERT INTO Users(id, weight, desiredWeight) VALUES(1, 160, 145);

Jeśli próbujesz zmienić wagę / pożądane wartości wagi dla istniejącego wiersza o identyfikatorze 1, powinieneś użyć:

UPDATE Users SET weight = 160, desiredWeight = 145 WHERE id = 1;

Jeśli chcesz, możesz też użyć WSTAWIĆ .. W składni DUPLICATE KEY w następujący sposób:

INSERT INTO Users (id, weight, desiredWeight) VALUES(1, 160, 145) ON DUPLICATE KEY UPDATE weight=160, desiredWeight=145

LUB nawet tak:

INSERT INTO Users SET id=1, weight=160, desiredWeight=145 ON DUPLICATE KEY UPDATE weight=160, desiredWeight=145

Ważne jest również, aby pamiętać, że jeśli twoja idkolumna jest kolumną z autoinkrementacją, równie dobrze możesz pominąć ją w INSERT i pozwolić mysql inkrementować ją jak zwykle.

Chad Birch
źródło
1
Dzięki za dobrą odpowiedź. Podczas używania zapytania UPDATE działa dobrze. Ale gdy id jest kluczem podstawowym i kluczem automatycznej inkrementacji, powyższa instrukcja INSERT nie działa. Błąd Zduplikowany wpis '1' dla klucza 1.
JDGuide
1
@JDeveloper To dlatego, że wiersz już istnieje. Jak wspomniał Chad If you're trying to insert a new row with ID 1 you should be usingINSERT INTO. W twoim przypadku próbujesz wstawić, gdy ID 1 już istnieje i jest to klucz podstawowy lub unikalny i kończy się niepowodzeniem, więc powinieneś użyć składni UPDATE lub INSERT .. W składni DUPLICATE KEY
Anthony Hatzopoulos
41

Nie można łączyć klauzuli WHERE z klauzulą ​​VALUES. O ile wiem, masz dwie opcje:

  1. INSERT określając wartości

    INSERT INTO Users(weight, desiredWeight) 
    VALUES (160,145)
  2. INSERT przy użyciu instrukcji SELECT

    INSERT INTO Users(weight, desiredWeight) 
    SELECT weight, desiredWeight 
    FROM AnotherTable 
    WHERE id = 1
Russ Cam
źródło
19

Klauzula WHERE jest używana do zapytań UPDATE. Kiedy WSTAWISZ, zakładasz, że wiersz nie istnieje.

Oświadczenie PO stałoby się wtedy;

UPDATE Użytkownicy SET waga = 160, pożądana waga = 45, gdzie id = 1;

W MySQL, jeśli chcesz INSERT lub UPDATE, możesz użyć zapytania REPLACE z klauzulą ​​WHERE. Jeśli GDZIE nie istnieje, WSTAWIA, w przeciwnym razie AKTUALIZUJE.

EDYTOWAĆ

Myślę, że punkt widzenia Billa Karwina jest na tyle ważny, że można go wyrwać z komentarzy i uczynić go bardzo oczywistym. Dzięki Bill, minęło zbyt dużo czasu odkąd pracowałem z MySQL, przypomniałem sobie, że miałem problemy z REPLACE, ale zapomniałem, czym one są. Powinienem to sprawdzić.

Nie tak działa REPLACE MySQL. Wykonuje DELETE (co może oznaczać brak operacji, jeśli wiersz nie istnieje), po którym następuje INSERT. Pomyśl o konsekwencjach vis. wyzwalacze i zależności kluczy obcych. Zamiast tego użyj INSERT ... ON DUPLICATE KEY UPDATE.

Rob Prouse
źródło
7
Nie tak działa REPLACE MySQL. Wykonuje DELETE (co może oznaczać brak operacji, jeśli wiersz nie istnieje), po którym następuje INSERT. Pomyśl o konsekwencjach vis. wyzwalacze i zależności kluczy obcych. Zamiast tego użyj INSERT ... ON DUPLICATE KEY UPDATE.
Bill Karwin
10

Nie sądzę, aby wstawka zawierała klauzulę WHERE.

Daniel A. White
źródło
To prawda i piasek w tym samym czasie!
Ingus
5

Wstaw zapytanie nie obsługuje, gdzie słowo kluczowe *

Obowiązują warunki, ponieważ możesz użyć warunku where dla instrukcji wyboru podrzędnego. Możesz wykonywać skomplikowane wstawki za pomocą sub-selekcji.

Na przykład:

INSERT INTO suppliers
(supplier_id, supplier_name)
SELECT account_no, name
FROM customers
WHERE city = 'Newark';

Umieszczając opcję „wybierz” w instrukcji wstawiania, można szybko wykonać wielokrotne wstawianie.

W przypadku tego typu wstawiania możesz chcieć sprawdzić liczbę wstawianych wierszy. Możesz określić liczbę wierszy, które zostaną wstawione, uruchamiając następującą instrukcję SQL przed wykonaniem wstawiania.

SELECT count(*)
FROM customers
WHERE city = 'Newark';

Możesz upewnić się, że nie wstawiasz zduplikowanych informacji, używając warunku EXISTS.

Na przykład, jeśli masz tabelę o nazwie klientów z kluczem podstawowym client_id, możesz użyć następującej instrukcji:

INSERT INTO clients
(client_id, client_name, client_type)
SELECT supplier_id, supplier_name, 'advertising'
FROM suppliers
WHERE not exists (select * from clients
where clients.client_id = suppliers.supplier_id);

Ta instrukcja wstawia wiele rekordów z podselekcją.

Jeśli chcesz wstawić pojedynczy rekord, możesz użyć następującej instrukcji:

INSERT INTO clients
(client_id, client_name, client_type)
SELECT 10345, 'IBM', 'advertising'
FROM dual
WHERE not exists (select * from clients
where clients.client_id = 10345);

Użycie tabeli podwójnej umożliwia wprowadzenie wartości w instrukcji select, nawet jeśli wartości nie są obecnie przechowywane w tabeli.

Zobacz także Jak wstawiać z klauzulą ​​where

Somnath Muluk
źródło
4

Prawidłowa odpowiedź na to pytanie będzie wyglądać następująco:

za). JEŚLI chcesz wybrać przed wstawieniem:

INSERT INTO Users( weight, desiredWeight ) 
  select val1 , val2  from tableXShoulatNotBeUsers
  WHERE somecondition;

b). JEŚLI rekord już istnieje, użyj aktualizacji zamiast wstawiania:

 INSERT INTO Users( weight, desiredWeight ) VALUES ( 160, 145 ) WHERE id = 1;

Powinien być

Update Users set weight=160, desiredWeight=145  WHERE id = 1;

do). Jeśli chcesz zaktualizować lub wstawić w tym samym czasie

Replace Users set weight=160, desiredWeight=145  WHERE id = 1;

Note):- you should provide values to all fields else missed field in query 
        will be set to null

re). Jeśli chcesz SKLONOWAĆ rekord z TEJ SAMEJ tabeli, pamiętaj tylko, że nie możesz wybrać z tabeli, do której wstawiasz

 create temporary table xtable ( weight int(11), desiredWeight int(11) ;

 insert into xtable (weight, desiredWeight) 
    select weight, desiredWeight from Users where [condition]

 insert into Users (weight, desiredWeight) 
    select weight , desiredWeight from xtable;

Myślę, że to całkiem pokrywa większość scenariuszy

sakhunzai
źródło
3

Po prostu nie możesz użyć WHERE podczas wykonywania instrukcji INSERT:

 INSERT INTO Users( weight, desiredWeight ) VALUES ( 160, 145 ) WHERE id = 1;

Powinien być:

 INSERT INTO Users( weight, desiredWeight ) VALUES ( 160, 145 );

Część WHERE działa tylko w instrukcjach SELECT:

SELECT from Users WHERE id = 1;

lub w instrukcjach UPDATE:

UPDATE Users set (weight = 160, desiredWeight = 145) WHERE id = 1;
Borniet
źródło
2

Insert into = Dodawanie wierszy do tabeli

Upate = aktualizuj określone wiersze.

Co opisałaby klauzula Where w Twojej wstawce? Nie ma nic do dopasowania, wiersz nie istnieje (jeszcze) ...

Richard L.
źródło
2

Możesz wykonać warunkowe INSERT na podstawie danych wprowadzonych przez użytkownika. To zapytanie wstawi tylko wtedy, gdy zmienne wejściowe '$ userWeight' i '$ userDesiredWeight' nie są puste

INSERT INTO Users(weight, desiredWeight )
select '$userWeight', '$userDesiredWeight'  
FROM (select 1 a ) dummy
WHERE '$userWeight' != '' AND '$userDesiredWeight'!='';
Igor Vujovic
źródło
1

Zależy to od sytuacji, w której INSERT może faktycznie mieć klauzulę where.

Na przykład, jeśli dopasowujesz wartości z formularza.

Consider INSERT INTO Users(name,email,weight, desiredWeight) VALUES (fred,bb@yy.com,160,145) WHERE name != fred AND email != bb@yy.com

To ma sens, prawda?

Frank Nwoko
źródło
czy to możliwe, gdy klauzula w instrukcji wstawiania
Taja_100
1

Najprostszym sposobem jest użycie funkcji JEŻELI w celu naruszenia kluczowego ograniczenia. Działa to tylko dla INSERT IGNORE, ale pozwoli ci użyć ograniczenia w INSERT.

INSERT INTO Test (id, name) VALUES (IF(1!=0,NULL,1),'Test');
Ethan Brooks
źródło
1

Po WHEREKlauzula umieszcza warunek, który jest używany do pobierania danych lub do aktualizowania wiersza. Podczas wstawiania danych zakłada się, że wiersz nie istnieje.

A więc pytanie brzmi, czy istnieje wiersz o identyfikatorze 1? jeśli tak, użyj MySQL UPDATE , w przeciwnym razie użyj MySQL INSERT .

Revathi
źródło
1

Jeśli określasz konkretny rekord nie do wstawiania danych, lepiej jest użyć UPDATEinstrukcji zamiastINSERT instrukcji.

Ten typ zapytania, które wpisałeś w pytaniu, jest jak zapytanie fikcyjne.

Twoje zapytanie to: -

INSERT INTO Users( weight, desiredWeight ) VALUES ( 160, 145 ) WHERE id = 1;

Tutaj UPDATEokreślasz id = 1, więc lepiej użyj instrukcji do aktualizacji istniejącego rekordu.Nie zaleca się używania WHEREklauzuli w przypadku INSERT.UPDATE .

Teraz korzystam z zapytania aktualizacyjnego: -

UPDATE Users SET weight=160,desiredWeight=145 WHERE id=1;
JDGuide
źródło
Żadne zapytanie mate. 1-sze zapytanie nie zadziała. 1-sze zapytanie to zadane pytanie.
JDGuide
Dlaczego sugerujesz aktualizację zamiast wstawiania? Użytkownik chce wstawić wartości z warunkiem i nie aktualizować wychodzących rekordów.
Somnath Muluk
1

Czy w każdym przypadku klauzula WHERE może być faktycznie używana z INSERT-INTO-VALUES?

Odpowiedź brzmi: zdecydowanie nie.

Dodanie klauzuli WHERE po INSERT INTO ... VALUES ... jest po prostu nieprawidłowym kodem SQL i nie zostanie przeanalizowane.

Błąd zwracany przez MySQL to:

mysql> INSERT INTO Users( weight, desiredWeight ) VALUES ( 160, 145 ) WHERE id = 1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE id = 1' at line 1

Najważniejszą częścią komunikatu o błędzie jest

... syntax to use near 'WHERE id = 1' ...

która pokazuje konkretną część, której parser nie spodziewał się znaleźć w tym miejscu: klauzula WHERE.

Marc Alff
źródło
1

jego totalnie źle. INSERT QUERY nie ma klauzuli WHERE, ma ją tylko UPDATE QUERY. Jeśli chcesz dodać dane, gdzie id = 1, wtedy Twoje zapytanie będzie

UPDATE Users SET weight=160, desiredWeight= 145 WHERE id = 1;
Asmarah
źródło
1

Nie. O ile wiem, nie możesz dodać klauzuli WHERE do tego zapytania. Może zapomniałem też o swoim SQL-u, ponieważ nie jestem pewien, dlaczego go potrzebujesz.

Ikechi Anyanwu
źródło
1

Nie należy używać warunku gdzie w instrukcji Wstaw. Jeśli chcesz, użyj wstawiania w instrukcji aktualizacji, a następnie zaktualizuj istniejący rekord.

Właściwie mogę wiedzieć, dlaczego potrzebujesz klauzuli gdzie w instrukcji wstawiania?

Może w oparciu o powód, mogę zasugerować lepszą opcję.

Krishna Thota
źródło
1

Myślę, że najlepszą opcją jest użycie REPLACE zamiast INSERT

ZAMIEŃ NA użytkowników (id, waga, pożądana waga) WARTOŚCI (1, 160, 145);

Alberto León
źródło
1

PRZECZYTAJ TO TAKŻE

To nie ma sensu ... nawet dosłownie

INSERToznacza dodanie a, new rowa kiedy mówisz WHERE, definiujesz, o którym wierszu mówisz w SQL.

Dlatego dodanie nowego wiersza nie jest możliwe, jeśli warunek dotyczy istniejącego wiersza.

Masz do wyboru:

A. Użyj UPDATEzamiastINSERT

B. Użyj INSERTi usuń WHEREklauzulę (właśnie to mówię ...) lub jeśli jesteś naprawdę zobowiązany do użycia INSERTiw WHEREpojedynczym oświadczeniu można to zrobić tylko za pomocą klauzuli INSERT..SELECT ...

INSERT INTO Users( weight, desiredWeight ) 
SELECT FROM Users WHERE id = 1;

Ale służy to zupełnie innemu celowi i jeśli zdefiniowałeś id jako klucz podstawowy, to wstawienie zakończy się niepowodzeniem, w przeciwnym razie zostanie wstawiony nowy wiersz z id = 1.

Bharat Sinha
źródło
tak, masz rację, wiedząc, że wszystkie te rzeczy budzą się i popełniają błędy.
Asesha George
1

Zdaję sobie sprawę, że to stary post, ale mam nadzieję, że to jeszcze komuś pomoże, mam nadzieję, że jest to prosty przykład:

tło:

Miałem wiele do wielu przypadków: ten sam użytkownik jest wymieniony wiele razy z wieloma wartościami i chciałem utworzyć nowy rekord, dlatego UPDATE nie miałoby sensu w moim przypadku i musiałem zwrócić się do konkretnego użytkownika, tak jakbym zrobił używając klauzuli WHERE.

INSERT into MyTable(aUser,aCar)
value(User123,Mini)

Używając tej konstrukcji, w rzeczywistości kierujesz się na konkretnego użytkownika (user123, który ma inne rekordy), więc tak naprawdę nie potrzebujesz klauzuli where, tak sądzę.

wynikiem może być:

aUser   aCar
user123 mini
user123 HisOtherCarThatWasThereBefore
Ylenia88m
źródło
1

Sposób użycia INSERT i WHERE is

INSERT INTO MYTABLE SELECT 953,'Hello',43 WHERE 0 in (SELECT count(*) FROM MYTABLE WHERE myID=953); W tym przypadku jest to test istnienia. Nie ma wyjątku, jeśli uruchomisz go dwa lub więcej razy ...

Obrabować
źródło
0

poprawna składnia wstawiania mysql do instrukcji przy użyciu metody post to:

$sql="insert into ttable(username,password) values('$_POST[username]','$_POST[password]')";
chaitanya koripella
źródło
1
Musisz wymknąć się niezaufanym parametrom, takim jak nazwa użytkownika, lub użyć zapytań parametrycznych, aby uniemożliwić atakującemu wstrzyknięcie dowolnych poleceń SQL . I użyj jednego z algorytmów HashCrypt do przechowywania hasła.
Hendrik Brummermann
0

Nie sądzę, abyśmy mogli użyć klauzuli where w instrukcji wstawiania

Nipun Jain
źródło
0
INSERT INTO Users(weight, desiredWeight )
SELECT '$userWeight', '$userDesiredWeight'  
FROM (select 1 a ) dummy
WHERE '$userWeight' != '' AND '$userDesiredWeight'!='';
user6297694
źródło
1
Czy możesz edytować proponowaną odpowiedź, aby rozwinąć, co to robi i jak odnosi się do PO?
Ro Yo Mi
0

Nie możesz używać razem INSERT i WHERE. Możesz użyć klauzuli UPDATE, aby dodać wartość do określonej kolumny w określonym polu, jak poniżej;

UPDATE Users
SET weight='160',desiredWeight ='145'  
WHERE id =1
Vishal Vaishnav
źródło
0

Myślę, że prawidłową formą wstawiania wartości w określonym wierszu jest:

UPDATE table SET column = value WHERE columnid = 1

działa i jest podobnie, jeśli piszesz na serwerze Microsoft SQL Server

INSERT INTO table(column) VALUES (130) WHERE id = 1;

na mysql musisz zaktualizować tabelę.

Jonathan JS
źródło
0

Możesz to zrobić za pomocą poniższego kodu:

INSERT INTO table2 (column1, column2, column3, ...)
SELECT column1, column2, column3, ...
FROM table1
WHERE condition
KimchiMan
źródło