sql >> Database >  >> RDS >> Mysql

MySQL's INSERT IGNORE INTO &buitenlandse sleutels

[NIEUW ANTWOORD]

Met dank aan @NeverEndingQueue om dit ter sprake te brengen. Het lijkt erop dat MySQL dit probleem eindelijk heeft opgelost. Ik weet niet zeker in welke versie dit probleem voor het eerst is opgelost, maar op dit moment heb ik getest met de volgende versie en het probleem is er niet meer:

mysql> SHOW VARIABLES LIKE "%version%";
+-------------------------+------------------------------+
| Variable_name           | Value                        |
+-------------------------+------------------------------+
| innodb_version          | 5.7.22                       |
| protocol_version        | 10                           |
| slave_type_conversions  |                              |
| tls_version             | TLSv1,TLSv1.1                |
| version                 | 5.7.22                       |
| version_comment         | MySQL Community Server (GPL) |
| version_compile_machine | x86_64                       |
| version_compile_os      | Linux                        |
+-------------------------+------------------------------+

Voor de duidelijkheid:

mysql> INSERT IGNORE INTO child
    -> VALUES
    ->     (NULL, 1)
    ->     , (NULL, 2)
    ->     , (NULL, 3)
    ->     , (NULL, 4)
    ->     , (NULL, 5)
    ->     , (NULL, 6);
Query OK, 4 rows affected, 2 warnings (0.03 sec)
Records: 6  Duplicates: 2  Warnings: 2

Ga verder met het oude antwoord hieronder om de betekenis van deze laatste vraag beter te begrijpen en waarom het aangeeft dat het probleem is opgelost.

[OUD ANTWOORD]

Mijn oplossing is een omzeiling van het probleem en de daadwerkelijke oplossing zal altijd het probleem binnen de MySQL zelf oplossen.

De volgende stappen hebben mijn probleem opgelost:

a. Overweeg de volgende tabellen en gegevens te hebben:

mysql>
CREATE TABLE parent (id INT AUTO_INCREMENT NOT NULL
                     , PRIMARY KEY (id)
) ENGINE=INNODB;

mysql>
CREATE TABLE child (id INT AUTO_INCREMENT
                    , parent_id INT
                    , INDEX par_ind (parent_id)
                    , PRIMARY KEY (id)
                    , FOREIGN KEY (parent_id) REFERENCES parent(id)
                        ON DELETE CASCADE
                        ON UPDATE CASCADE
) ENGINE=INNODB;

mysql>
INSERT INTO parent
VALUES (NULL), (NULL), (NULL), (NULL), (NULL), (NULL);

mysql>
SELECT * FROM parent;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
|  6 |
+----+

b. Nu moeten we enkele rijen verwijderen om het probleem aan te tonen:

mysql>
DELETE FROM parent WHERE id IN (3, 5);

c. PROBLEEM: Het probleem doet zich voor wanneer u de volgende onderliggende rijen probeert in te voegen:

mysql>
INSERT IGNORE INTO child
VALUES
    (NULL, 1)
    , (NULL, 2)
    , (NULL, 3)
    , (NULL, 4)
    , (NULL, 5)
    , (NULL, 6);

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint f
ails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERE
NCES `parent` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)

mysql>
SELECT * FROM child;
Empty set (0.00 sec)

Hoewel de IGNORE trefwoord wordt gebruikt, maar MySQL annuleert de gevraagde bewerking omdat de gegenereerde fout niet wordt omgezet in een waarschuwing (zoals het hoort). Nu het probleem duidelijk is, laten we eens kijken hoe we de laatste invoeging in de instructie kunnen uitvoeren zonder fouten te maken.

d. OPLOSSING: Ik ga het tussenvoegsel in een verklaring verpakken met enkele andere constante verklaringen die niet afhankelijk zijn van de ingevoegde records, noch van hun aantal.

mysql>
SET FOREIGN_KEY_CHECKS = 0;

mysql>
INSERT INTO child
VALUES
    (NULL, 1)
    , (NULL, 2)
    , (NULL, 3)
    , (NULL, 4)
    , (NULL, 5)
    , (NULL, 6);

mysql>
DELETE FROM child WHERE parent_id NOT IN (SELECT id FROM parent);

mysql>
SET FOREIGN_KEY_CHECKS = 1;

Ik weet dat dit niet optimaal is, maar zolang MySQL het probleem niet heeft opgelost, is dit het beste dat ik ken. Vooral omdat alle instructies in één verzoek kunnen worden uitgevoerd als je de mysqli-bibliotheek in PHP gebruikt.



  1. Tabel converteren van MyISAM naar INNODB

  2. WAARDEN-clausule in SQL Server

  3. MySQL:toegang geweigerd voor gebruiker 'test'@'localhost' (met wachtwoord:JA) behalve rootgebruiker

  4. Hoe Asin() werkt in PostgreSQL