|
| UPDATE: mærkeligt problem med duplicate en~ Fra : Daniel Overby |
Dato : 17-08-05 16:14 |
|
Hej
Via PHP udfører jeg en UPDATE i min MySQL database. Men jeg får en error
tilbage, når min PHP applikation udfører forespøgslen. Den melder fejl pga.
duplicate entry. Hvis jeg kører samme forespørgsel via PhpMyAdmin, får jeg
ingen fejl og dataene ændres som planlagt.
Min forespørgsel ser sådan ud
UPDATE mobilephone SET masterProductID = null, active=1 WHERE
refindKey='23b4b23y98adf23'
masterProductID danner sammen med en anden attribut et index/unique.Der er
andre poster i tabellen, der har null i masterProductID, hvor der ikke er
problemer.
Hvad kan jeg have overset?
- Daniel
| |
Carsten Pedersen (17-08-2005)
| Kommentar Fra : Carsten Pedersen |
Dato : 17-08-05 18:44 |
|
Hej, Daniel!
"Daniel Overby" <mailFJERN@overbyhansenFJERN.dk> skrev i en meddelelse
news:43035450$0$78283$157c6196@dreader1.cybercity.dk...
> Hej
>
> Via PHP udfører jeg en UPDATE i min MySQL database. Men jeg får en error
> tilbage, når min PHP applikation udfører forespøgslen. Den melder fejl
> pga. duplicate entry. Hvis jeg kører samme forespørgsel via PhpMyAdmin,
> får jeg ingen fejl og dataene ændres som planlagt.
>
> Min forespørgsel ser sådan ud
>
> UPDATE mobilephone SET masterProductID = null, active=1 WHERE
> refindKey='23b4b23y98adf23'
>
> masterProductID danner sammen med en anden attribut et index/unique.Der er
> andre poster i tabellen, der har null i masterProductID, hvor der ikke er
> problemer.
>
> Hvad kan jeg have overset?
Sandsynligvis den anden attribut i den post, du forsøger at rette. Den har
sikkert samme værdi som i en af de andre poster, hvor masterProductID er
null, så når du opdaterer denne post, får du to poster med samme unikke
indeks, og det er det, den laver vrøvl over.
Mvh
C@rsten
| |
Daniel Overby (17-08-2005)
| Kommentar Fra : Daniel Overby |
Dato : 17-08-05 19:10 |
|
> Sandsynligvis den anden attribut i den post, du forsøger at rette. Den har
> sikkert samme værdi som i en af de andre poster, hvor masterProductID er
> null, så når du opdaterer denne post, får du to poster med samme unikke
> indeks, og det er det, den laver vrøvl over.
Ja, i den post jeg vil rette, får jeg de to attributter, der danner nøglen,
samme værdi. Men det gør det på hundredevis af andre poster, da de har en
defaultværdi. Det sjove er jo, at jeg kan køre samme forespørgsel via
PhpMyAdmin, hvor det virker!
Jeg troede, at den så bort fra Unique-nøglen, når en af værdierne er null.
- Daniel
| |
Carsten Pedersen (18-08-2005)
| Kommentar Fra : Carsten Pedersen |
Dato : 18-08-05 19:08 |
|
Hej, Daniel!
"Daniel Overby" <mailFJERN@overbyhansenFJERN.dk> skrev i en meddelelse
news:43037d7a$0$78283$157c6196@dreader1.cybercity.dk...
>> Sandsynligvis den anden attribut i den post, du forsøger at rette. Den
>> har sikkert samme værdi som i en af de andre poster, hvor masterProductID
>> er null, så når du opdaterer denne post, får du to poster med samme
>> unikke indeks, og det er det, den laver vrøvl over.
>
> Ja, i den post jeg vil rette, får jeg de to attributter, der danner
> nøglen, samme værdi. Men det gør det på hundredevis af andre poster, da de
> har en defaultværdi. Det sjove er jo, at jeg kan køre samme forespørgsel
> via PhpMyAdmin, hvor det virker!
>
> Jeg troede, at den så bort fra Unique-nøglen, når en af værdierne er null.
Det gør den ikke, da null også er en værdi, selv om den er ingenting.
Når man benytter to attributter i en tabel til at danne den unikke nøgle, er
det fordi samme værdi kan forekomme adskillige gange i hver af
attributterne, men en bestemt kombination af værdier kun kan forekomme én
gang, så den pågældende række derved kan identificeres entydigt.
Forestil dig, at den virkeligt så bort fra unikke nøgler, når den ene af
nøglens attributter er null. Du vil så risikere at stå med to eller flere
poster med samme "unikke" værdi. Senere ønsker du så at ændre din
masterProductID til noget andet end null i en - og kun en - af disse poster.
Men hvordan skal databasen så kunne vide hvilken post, du vel ændre? Det kan
den ikke og ændrer dem alle sammen, og så er du lige vidt.
Det er heller ikke nogen god ide at anvende null eller andre defaultværdier
i attributter, som danner unikke nøgler. Du skal alligevel ind og ændre en
eller begge værdier for at holde nøglen unik.
Mvh
C@rsten
| |
Peter Brodersen (18-08-2005)
| Kommentar Fra : Peter Brodersen |
Dato : 18-08-05 20:00 |
|
On Thu, 18 Aug 2005 20:08:01 +0200, "Carsten Pedersen"
<Carsten.Pedersen@invalid.invalid> wrote:
>> Jeg troede, at den så bort fra Unique-nøglen, når en af værdierne er null.
>Det gør den ikke, da null også er en værdi, selv om den er ingenting.
Det er nu ikke rigtigt - jeg ved ikke om det er unikt for MySQL, men:
mysql> CREATE TABLE a (foo int, bar int, unique index(foo, bar));
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO a (foo, bar) VALUES (1,1);
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO a (foo, bar) VALUES (1,1);
ERROR 1062 (23000): Duplicate entry '1-1' for key 1
mysql> INSERT INTO a (foo, bar) VALUES (1,2);
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO a (foo, bar) VALUES (2,1);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO a (foo, bar) VALUES (1,NULL);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO a (foo, bar) VALUES (1,NULL);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO a (foo, bar) VALUES (NULL,NULL);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO a (foo, bar) VALUES (NULL,NULL);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO a (foo, bar) VALUES (NULL,1);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO a (foo, bar) VALUES (NULL,1);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM a;
+------+------+
| foo | bar |
+------+------+
| NULL | NULL |
| NULL | NULL |
| NULL | 1 |
| NULL | 1 |
| 1 | NULL |
| 1 | NULL |
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
+------+------+
9 rows in set (0.00 sec)
mysql> SELECT * FROM a WHERE foo = bar;
+------+------+
| foo | bar |
+------+------+
| 1 | 1 |
+------+------+
1 row in set (0.00 sec)
mysql> SELECT a.foo, a.bar FROM a, a AS b WHERE (a.foo = b.foo AND
a.bar = b.bar);
+------+------+
| foo | bar |
+------+------+
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
+------+------+
3 rows in set (0.00 sec)
>Når man benytter to attributter i en tabel til at danne den unikke nøgle, er
>det fordi samme værdi kan forekomme adskillige gange i hver af
>attributterne, men en bestemt kombination af værdier kun kan forekomme én
>gang, så den pågældende række derved kan identificeres entydigt.
Nu er NULL jo ikke blot en værdi som enhver anden.
Idet (NULL = NULL) ikke giver TRUE, så kan man argumentere for at en
række med fx (NULL, 1) ikke er lig med en anden række med (NULL, 1).
Det ses også af de to sidste queries.
Med andre ord, det er tilladt direkte i MySQL. Jeg kan dog ikke se,
hvorfor problemet skulle opstå via PHP.
--
- Peter Brodersen
| |
Peter Brodersen (18-08-2005)
| Kommentar Fra : Peter Brodersen |
Dato : 18-08-05 20:13 |
|
On Thu, 18 Aug 2005 20:08:01 +0200, "Carsten Pedersen"
<Carsten.Pedersen@invalid.invalid> wrote:
>Det gør den ikke, da null også er en værdi, selv om den er ingenting.
... og lidt fra sql92, der argumenterer for at man godt må have flere
null-værdier i et unique index:
A unique constraint is satisfied if and only if no two rows in
a table have the same non-null values in the unique columns. In
addition, if the unique constraint was defined with PRIMARY KEY,
then it requires that none of the values in the specified column or
columns be the null value.
(der er ikke tale om en primærnøgle her)
Så jeg går ud fra at det er RDBMS-uafhængigt, og ikke en mysql-særhed.
--
- Peter Brodersen
| |
Daniel Overby (19-08-2005)
| Kommentar Fra : Daniel Overby |
Dato : 19-08-05 15:51 |
|
Hmmm - en masse ekstra viden om nøgler fik jeg da, men umiddelbart ingen
løsning. Jeg fjernede min nøgle, lavede et par indeks i stedet og håndterer
kravet om unikke poster via PHP.
- Daniel
| |
|
|