WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   Varför funkar inte denna SQL query? (https://www.wn.se/forum/showthread.php?t=1059719)

naak2803 2013-11-06 13:44

Varför funkar inte denna SQL query?
 
Hej,
jag har lite problem med en query..

UPDATE OfferCode SET status = 1, usedDate = '2013-01-01' WHERE id = (SELECT id FROM OfferCode WHERE code = 'vip' ORDER BY usedDate LIMIT 1)

anledning till att jag väljer att göra så är att db har dubletter av samma "code", och då vill jag endast uppdatera den första raden.

dvs
Kod:

[dbo.OfferCode]
code    status    usedDate
vip        0          2013-01-01
vip        0          2013-01-01
vip        0          2013-01-01
xxx      0          2013-01-01
yyy      0          2013-01-01
zzz        0          2013-01-01

ERROR [HY000] [MySQL][ODBC 5.1 Driver][mysqld-5.5.34]You can't specify target table 'OfferCode' for update in FROM clause

Det jag är ute efter att kunna uppdatera första raden med "code=vip" och sätta om statusen till "1"

Kod:

[dbo.OfferCode]
code    status    usedDate
vip        1          2013-01-01
vip        0          2013-01-01
vip        0          2013-01-01
xxx      0          2013-01-01
yyy      0          2013-01-01
zzz        0          2013-01-01


ANttila 2013-11-06 14:09

Kod:

UPDATE OfferCode SET status = 1 WHERE code = 'vip' ORDER BY usedDate LIMIT 1
Är jag helt ute o cyklar nu, eller är det så här du vill ha det?

H S Consulting 2013-11-06 14:09

Det går inte att köra en select subquery mot samma tabell som ska uppdateras.
Finns det någon förklarlig anledning till att du intehar ett fält i tabellen med auto increment så att varje post får ett unikt ID som du kan använda i din query?

allstars 2013-11-06 14:52

Rätt smalt designad tabell måste jag säga.

Så här skulle jag gjort en tabell för kuponger

ID (int eller guid) - Index
Identifier (varchar) - Den kod som användaren fyller i
Enabled (bool) - om kupongen är aktiv
ValueSEK (int) - Det som dras av, i SEK
ValuePercent (decimal) - Det som dras av, i procent
IssueDate (datetime) - När är den skapad
ValidToDate (datetime) - Hur länge den ska vara giltig
IssuedToUser (int) - Om kupongen gäller en viss användare, annars 0
ValidCount (int) - Hur många kuponger som finns, 0 för obefintliga
MultiplePerUser (bool) - Om samma användare kan använda kupongen flera gånger

Möjliga påbyggnationer är att man kan ange produktID som kupongen gäller för.


Sedan gärna komplettera med en tabell som säger vilken användare som använt vilken kod, för kontrollera om användaren använt den innan. Då räknar man inte ner ValidCount utan slår upp i den andra tabellen och jämför med värdet i ValidCount.

Westman 2013-11-06 17:24

Kort svar: Stored procedure.

Conny Westh 2013-11-06 18:02

Citat:

Ursprungligen postat av naak2803 (Inlägg 20480538)
Hej,
jag har lite problem med en query..

UPDATE OfferCode SET status = 1, usedDate = '2013-01-01' WHERE id = (SELECT id FROM OfferCode WHERE code = 'vip' ORDER BY usedDate LIMIT 1)

anledning till att jag väljer att göra så är att db har dubletter av samma "code", och då vill jag endast uppdatera den första raden.

dvs
Kod:

[dbo.OfferCode]
code    status    usedDate
vip        0          2013-01-01
vip        0          2013-01-01
vip        0          2013-01-01
xxx      0          2013-01-01
yyy      0          2013-01-01
zzz        0          2013-01-01

ERROR [HY000] [MySQL][ODBC 5.1 Driver][mysqld-5.5.34]You can't specify target table 'OfferCode' for update in FROM clause

Det jag är ute efter att kunna uppdatera första raden med "code=vip" och sätta om statusen till "1"

Kod:

[dbo.OfferCode]
code    status    usedDate
vip        1          2013-01-01
vip        0          2013-01-01
vip        0          2013-01-01
xxx      0          2013-01-01
yyy      0          2013-01-01
zzz        0          2013-01-01


Du har ju ingen primärnyckel i tabellen!!!! Då går det inte att adressera enstaka rader om det finns duplicerade datavärden. Man bygger ALDRIG en relationsdatabas utan primärnyckel!!!

Det är i och för sig en sanning med modifikation eftersom man kan använda ROWID som brukar finnas i alla moderna relationsdatabaser, det är ett unikt id som man kan använda i nödfall, men inget man ska bygga sin applikation på för det funkar olika beroende på vilken databasmotor det är.

pelmered 2013-11-06 18:51

Citat:

Ursprungligen postat av allstars (Inlägg 20480546)
Rätt smalt designad tabell måste jag säga.

Så här skulle jag gjort en tabell för kuponger

ID (int eller guid) - Index
Identifier (varchar) - Den kod som användaren fyller i
Enabled (bool) - om kupongen är aktiv
ValueSEK (int) - Det som dras av, i SEK
ValuePercent (decimal) - Det som dras av, i procent
IssueDate (datetime) - När är den skapad
ValidToDate (datetime) - Hur länge den ska vara giltig
IssuedToUser (int) - Om kupongen gäller en viss användare, annars 0
ValidCount (int) - Hur många kuponger som finns, 0 för obefintliga
MultiplePerUser (bool) - Om samma användare kan använda kupongen flera gånger

Möjliga påbyggnationer är att man kan ange produktID som kupongen gäller för.


Sedan gärna komplettera med en tabell som säger vilken användare som använt vilken kod, för kontrollera om användaren använt den innan. Då räknar man inte ner ValidCount utan slår upp i den andra tabellen och jämför med värdet i ValidCount.

Det känns betydligt vettigare med en tabell med själva kuponginformationen och sedan ytterligare en kopplingstabell kopplad till användartabellen där information om själva transaktionen som t.ex. belopp, datum och vilken användare som använt kupongen(både användar-id och kupong-id).
Man vill separera entiteten(kupongen) med den här typen av metadata. En kupongkod ska bara finnas på ett ställe och om den används flera gånger så ska man skapa flera referenser, inte flera rader i kupongtabellen.


Alla tider är GMT +2. Klockan är nu 06:36.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson