2012-02-26 13 views
24

Come posso creare una sequenza su una tabella in modo che passi da 0 a> Valore massimo? Ho provato utilizzando il seguente codice SQL, ma non inserisce alcun valore nella tabella che sto usando:Creazione di una sequenza su una tabella esistente

CREATE SEQUENCE rid_seq; 
ALTER TABLE test ADD COLUMN rid INTEGER; 
ALTER TABLE test ALTER COLUMN rid SET DEFAULT nextval('rid_seq'); 

La tabella che sto cercando di inserire la sequenza è l'uscita da un'altra query. Non riesco a capire se abbia più senso aggiungere la sequenza durante questa query iniziale o aggiungere la sequenza alla tabella dopo che la query è stata eseguita.

risposta

-3

Non sono fluente in postgresql quindi non ho familiarità con la dichiarazione "CREATE SEQUENCE". Penserei, però, che stai aggiungendo la definizione della colonna correttamente. Tuttavia, l'aggiunta della colonna non inserisce automaticamente i dati per le righe esistenti. Un vincolo DEFAULT è per le nuove righe. Prova ad aggiungere qualcosa di simile in seguito per popolare i dati sulle righe esistenti.

DECLARE @i Int 
SET @i = 0 
SET ROWCOUNT 1 
WHILE EXISTS (SELECT 1 FROM test WHERE rid IS NULL) BEGIN 
    UPDATE test SET rid = @i WHERE rid IS NULL 
END 
SET ROWCOUNT 0 
+0

Grazie per il frammento. Sto cercando errori di sintassi quando cerco di eseguirlo: 'at or near @'. Non ho familiarità con la definizione delle variabili in Postgreqsl, quindi non sono sicuro se c'è qualcosa di ovvio che devo cambiare. – djq

+0

(1) Che assomiglia a SQL Server o forse sintassi MySQL, non funzionerà in PostgreSQL. (2) Ciò causerà qualche problema non appena vengono aggiunte nuove righe in quanto non si stanno usando i valori della sequenza, il valore successivo che esce dalla sequenza sarà 1 anche se l'hai già usato per un ' RID. –

+0

Buona cattura, [mu è troppo corto] (http://stackoverflow.com/users/479863/mu-is-too-short), su come non usare i valori della sequenza. E sì, sono abbastanza bravo a scrivere codice MS SQL Server (con il quale avrei affrontato un po 'diversamente) e non ho affatto familiarità con PostgreSQL.Il punto che stavo tentando di fare era la differenza tra la definizione di un vincolo e l'applicazione, che la risposta upvoted spiega meglio di I. –

37

impostare il valore predefinito quando si aggiunge la nuova colonna:

create sequence rid_seq; 
alter table test add column rid integer default nextval('rid_seq'); 

Alterare il valore predefinito per le colonne esistenti non cambia i dati esistenti in quanto il database non ha alcun modo di sapere quali valori dovrebbero essere modificati ; non c'è il flag "this column has the default value" sui valori delle colonne, c'è solo il valore predefinito (originariamente NULL poiché non hai specificato altro) e il valore corrente (anche NULL) ma il modo per dire la differenza tra "NULL perché è il valore predefinito "e" NULL perché è stato impostato esplicitamente su NULL ". Quindi, quando lo fai in due passaggi:

  1. Aggiungi colonna.
  2. Modificare il valore predefinito.

PostgreSQL non applica il valore predefinito alla colonna appena aggiunta. Tuttavia, se si aggiunge la colonna e si fornisce il valore predefinito allo stesso tempo, PostgreSQL sa quali righe hanno il valore predefinito (tutte) in modo che possa fornire valori man mano che la colonna viene aggiunta.

Tra l'altro, probabilmente desidera un NOT NULL su quella colonna troppo:

create sequence rid_seq; 
alter table test add column rid integer not null default nextval('rid_seq'); 

E, come a_horse_with_no_name note, se si intende utilizzare solo rid_seq per la colonna test.rid allora si potrebbe desiderare di set its owner column a test.rid modo che la sequenza viene interrotta se la colonna viene rimossa:

alter sequence rid_seq owned by test.rid; 
+3

Probabilmente anche tu vuoi rendere quella colonna il "proprietario" della sequenza, in modo che PostgreSQL lo sappia appartiene a quella colonna: 'alter sequence rid_sequence owner to test.rid' –

+0

è possibile personalizzare il valore della sequenza come" REQ0001-REQ000N "nella tabella esistente? – Angger

+0

@Angger Le sequenze sono numeriche quindi non proprio. Puoi falsificarlo concatenando due colonne o concatenando una stringa con una sequenza autonoma. –

1

In PostgreSQL:

UPDATE your_table SET your_column = nextval('your_sequence') 
WHERE your_column IS NULL; 
Problemi correlati