sql >> Databáze >  >> Database Tools >> phpMyAdmin

Jak nastavit vztah mezi tabulkami v phpMyAdmin

Omezení cizího klíče tabulka2 znamená, že jakákoli hodnota customerId tabulky2 se musí objevit jako customerId v tabulce1. Chyba se zobrazuje, protože do tabulky 2 vkládáte customerID, které se v tabulce 1 nezobrazuje.

Protože DBMS generuje ID zákazníka tabulky1 automatickým přírůstkem, pokud vložíte řádek, musíte získat tuto hodnotu, abyste mohli do tabulky2 vložit řádek s tímto ID zákazníka.

Myslím, že říkáte „Již jsem vytvořil vztah mezi tabulkami1 a tabulkou2“, což znamená „deklaroval jsem omezení cizího klíče“. A myslím, že si myslíte, že to znamená "po vložení do tabulky1 DBMS použije automaticky vygenerovanou hodnotu klíče jako hodnotu cizího klíče, když vložím do tabulky2". Ale to neznamená. To musíte udělat sami. Omezení cizího klíče pouze znamená, že DBMS kontroluje, zda se každá hodnota customerId tabulky2 jeví jako hodnota customerId tabulky1.

Při vkládání do tabulky s cizím klíčem k danému klíči můžete a musíte použít jakoukoli dříve vloženou hodnotu klíče jako odpovídající hodnotu.

Chcete-li získat zpět automaticky inkrementovanou hodnotu klíče generovanou DBMS, použijte LAST_INSERT_ID() :

INSERT INTO table1 (CustomerName,Address,State)
VALUES('value1','value2','value3');
INSERT INTO table2 (customerId,product,cost)
VALUES(LAST_INSERT_ID(),'valueA','valueB');

K tomu slouží. Ale zde jsou problémy, pokud jej nepoužíváte.

Za prvé, pokud nejste v serializované transakci, musíte použít LAST_INSERT_ID(). Protože po vložení tabulky1, ale před vložením tabulky2, mohli ostatní přidat řádky a/nebo odstranit řádky včetně vašeho nového řádku a/nebo změnit řádky včetně vašeho nového řádku. Nemůžete se tedy spoléhat na to, že dotazování tabulky1 poté, co její vložení získá nějakou hodnotu customerId, o které víte, že jste ji přidali.

Za druhé, předpokládejme, že jste v serializované transakci a nepoužíváte LAST_INSERT_ID().

If (CustomerName,Address,State) je také superklíč tabulky1, tj. jeho hodnoty jsou jedinečné, tj. SQL UNIQUE/KEY/PK je deklarován ve všech nebo některých jeho sloupcích, pak jej můžete použít k dotazu na související nové customerId:

set @customerId = (
    SELECT customerId
    FROM table1
    WHERE CustomerName = 'value1'
    AND Address = 'value2'
    AND State = 'value3');
INSERT INTO table2 (customerId,product,cost)
VALUES(@customerId,'valueA','valueB');

Ale if (CustomerName,Address,State) není superklíč tabulky1, pak to nemůžete udělat. Protože další řádky, které jsou duplicitní pro tento podřádek, mohou být v tabulce1. Takže můžete získat více řádků zpět. Takže byste nevěděli, která je nejnovější. Místo toho musíte před vložením zadat dotaz na tabulku1, poté vložit a poté najít rozdíl mezi starou a novou sadou customerId:

CREATE TEMPORARY TABLE table1old (
    customerId (int) PRIMARY KEY
    );
INSERT INTO table1old
SELECT customerId FROM table1;

INSERT INTO table1 (CustomerName,Address,State)
VALUES('value1','value2','value3');

set @customerId = (
    SELECT customerId
    FROM table1
    WHERE CustomerName NOT IN table1old);
INSERT INTO table2 (customerId,product,cost)
VALUES(@customerId,'valueA','valueB');

Stačí použít LAST_INSERT_ID().

PS:Zajímavé je, že vzhledem k definicím tabulek by se v ideálním případě dalo napsat:

INSERT INTO (
    SELECT CustomerName,Address,State,A,B
    FROM table1 JOIN table2
    USING (CustomerId))
VALUES('value1','value2','value3','valueA','valueB')

protože výsledkem může být pouze jeden pár nových hodnot table1 &table2. Existují určité právní aktualizace prostřednictvím pohledů v SQL, ačkoli v současnosti žádná nezahrnuje více tabulek v MySQL




  1. Jak mohu migrovat web Drupal na Amazon Web Services EC2?

  2. Aktualizujte 1 sloupec ze záložního souboru SQL

  3. Odstraňte nebo deaktivujte tlačítko X zavřít zobrazené na RAP/RCP EditorPart

  4. Jak vyřešit Microsoft SQL Server. Chyba 233. Poskytovatel:Poskytovatel SSL