2013-05-13 16 views
5

Ho avuto alcuni problemi di inserimento di dati da un'altra tabella in una nuova. L'obiettivo sembrava un po 'come questo:INSERT INTO/SELECT DISTINCT ha causato la violazione della chiave primaria per un SYS_GUID

CREATE TABLE TEST_T (
     T_GUID RAW(16) DEFAULT SYS_GUID() NOT NULL, 
     T_VAL1 NUMBER(10) NOT NULL, 
     T_VAL2 VARCHAR2(10) NOT NULL, 
     PRIMARY KEY (T_GUID) 
) 

La versione semplificata della dichiarazione intendevo riempirlo con i dati:

INSERT INTO TEST_T (T_VAL1, T_VAL2) 
SELECT DISTINCT 
    CAST(SUBSTR(zip_code, 1,1) AS NUMBER) as t_val1, 
    zip_code as t_val2 
FROM OTHER_TABLE_T 
WHERE ... 
ORDER BY t_val1 

come io non sono fornendo un T_GUID valutate, avrei assunto che ne ottengo uno fornito dalla funzione SYS_GUID per ogni nuova riga. Ma qualcosa sta andando storto, e ottengo una violazione del vincolo di unicità per la chiave primaria.

Se rimuovo lo DISTINCT, l'istruzione ha esito positivo, ma ottengo molte voci duplicate. E, naturalmente, se fornisco esplicitamente una chiamata SYS_GUID() nel mio SELECT, questo ha esattamente lo stesso risultato.

Ora ho scoperto che se ho semplicemente messo un altro SELECT intorno miniera, funziona bene, senza violazioni di vincoli e le righe distinte vengono inseriti:

INSERT INTO ... 
SELECT x.* FROM (
    SELECT DISTINCT ... 
) x 

Quindi, da dove i GUID duplicati vengono? Se il set completo di righe non ha problemi, perché rimuovere le righe in modo distinto può causare problemi? Poiché SYS_GUID crea un identificatore univoco per ogni chiamata, posso solo immaginare che nel caso distinto venga chiamato solo una volta per l'intera clausola, che viene risolto dall'involucro circostante SELECT. Sarei molto felice se qualcuno potesse spiegare come l'esecuzione differisce in quel caso.

+0

Sei sicuro che il GUID vengono duplicati? Osservali molto attentamente, sembrano simili ma dovresti notare almeno un carattere diverso in ciascuno di essi. – GriffeyDog

+0

Il tuo codice sembra corretto. È possibile che si stia verificando un errore di Oracle, cercare "DUPLICATE SYS_GUID generato su AIX può portare a errori ORA-1 durante l'accodamento [ID 1371805.1]" su Il mio supporto Oracle. –

risposta

0

Sostituire CAST con to_number() e aggiungere guid. Metti alla prova la vostra selezione prima, quindi inserire ...:

SELECT DISTINCT 
    sys_guid() guid 
    To_Number(SUBSTR(zip_code, 1,1)) as t_val1, 
    zip_code as t_val2 
FROM OTHER_TABLE_T 
/

Distinto esempio GUID:

SELECT sys_guid() gid, deptno 
    FROM 
(
SELECT distinct deptno FROM scott.emp 
) 
ORDER BY deptno 
/

GID         DEPTNO 
------------------------------------------- 
DC9B9132492C1A45E04011AC3EEB463A 10 
DC9B9132492B1A45E04011AC3EEB463A 20 
DC9B9132492A1A45E04011AC3EEB463A 30 
+0

Grazie per il suggerimento 'to_number', ma questo non risolve il mio problema principale. Se introduco un sys_guid nella select, il distinto non filtra alcuna riga duplicata (ad esempio se ho più righe con lo stesso zip_code, ma un'altra colonna diversa). – mhd

+0

@mhd - Quindi sbarazzarsi di distinti: usa gruppo o esiste operatore ecc ... Perché usare guid invece di un certo tipo di sequenza ... – Art

+0

Scelta di progettazione qui al lavoro, la maggior parte delle tabelle ha GUID come ID PK. E sì, ci sono diverse soluzioni possibili e ho risolto il mio problema con un semplice comando di selezione. Ma è un po 'come il vecchio "Dottore, mi fa male il braccio quando lo faccio"/"Allora non farlo" scherzo. Per la mia educazione personale, mi piacerebbe sapere cosa c'è che non va nell'originale, se il mio concetto di modello relazionale è sbagliato o se è solo un bug. – mhd

1

provare qualcosa di simile:

insert into test_t(t_guid, t_val1, t_val2) 
    select sys_guid(), t_val1, t_val2 
    from (select distinct to_number(substr(zip_code, 1, 1)) as t_val1, zip_code as t_val2 
      from other_table_t 
      where ...) 
+0

Non ho nemmeno bisogno di farlo. Come ho scritto sopra, non appena seleziono 'select * from (select distinct ... ', funziona.Non ho una buona spiegazione del perché. – mhd

Problemi correlati