Come vincolare una tabella di database in modo che solo una riga possa avere un valore particolare in una colonna?

StackOverflow https://stackoverflow.com/questions/182262

  •  05-07-2019
  •  | 
  •  

Domanda

Utilizzando Oracle, se un valore di colonna può essere 'SÌ' o 'NO' è possibile vincolare una tabella in modo che solo una riga possa avere un valore 'SÌ'?

Preferirei ridisegnare la struttura della tabella ma questo non è possibile.

[UDPATE] Purtroppo in questa tabella non sono ammessi valori null.

È stato utile?

Soluzione

Utilizza un indice basato sulle funzioni:

create unique index only_one_yes on mytable
(case when col='YES' then 'YES' end);

Oracle indicizza solo le chiavi che non sono completamente nulle e l'espressione CASE qui assicura che tutti i valori 'NO' siano cambiati in null e quindi non indicizzati.

Altri suggerimenti

Questo è un hack kludgy, ma se la colonna consente NULL, allora puoi usare NULL al posto di " NO " e utilizzare "SÌ" proprio come prima. Applica un vincolo chiave univoco a quella colonna e non otterrai mai due "SÌ" valori, ma hanno ancora molti NO.

Aggiornamento: @Nick Pierpoint: suggerito di aggiungere un vincolo di controllo in modo che i valori della colonna siano limitati a solo "SÌ". e NULL. La sintassi è stata risolta nella sua risposta.

Dovrai controllare un articolo di Tom Kyte con esattamente questa domanda e la sua risposta:

http://tkyte.blogspot.com/2008/05 /another-of-day.html

Riepilogo: non utilizzare i trigger, non utilizzare transazioni autonome, utilizzare due tabelle.

Se usi un database Oracle, DEVI conoscere AskTom e ottenere i suoi libri.

Non funziona sulla definizione della tabella.

Tuttavia, se aggiorni la tabella utilizzando un trigger che chiama una procedura memorizzata, puoi assicurarti che solo una riga contenga " YES " ;.

  1. Imposta tutte le righe su " NO "
  2. Imposta la riga che desideri su SÌ

In seguito al mio commento a una risposta precedente di yukondude, aggiungerei un indice univoco e un vincolo di controllo:

create table mytest (
    yesorno varchar2(3 char)
);

create unique index uk_mytest_yesorno on mytest(yesorno);

alter table mytest add constraint ck_mytest_yesorno check (yesorno is null or yesorno = 'YES');

Oracle supporta qualcosa come indici filtrati (la scorsa settimana ho sentito che ad esempio MSSQL2008 lo fa)? Forse puoi definire una chiave unica che si applica solo alle righe con il valore " Sì " nella tua colonna.

Immagino che userei una seconda tabella per puntare alla riga appropriata nella tabella corrente. L'altra tabella potrebbe essere utilizzata anche per memorizzare valori di altre variabili.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top