2012-04-04 8 views
6

Si tenta di eliminare il vincolo univoco per la colonna in h2, precedentemente creato come info varchar(255) unique.Eliminazione del vincolo univoco per la colonna in H2

ho provato:

sql> alter table public_partner drop constraint (select distinct unique_index_name from in 
formation_schema.constraints where table_name='PUBLIC_PARTNER' and column_list='INFO'); 

ma senza successo (come segue):

Syntax error in SQL statement "ALTER TABLE PUBLIC_PARTNER DROP CONSTRAINT ([*]SELECT DISTI 
NCT UNIQUE_INDEX_NAME FROM INFORMATION_SCHEMA.CONSTRAINTS WHERE TABLE_NAME='PUBLIC_PARTNER 
' AND COLUMN_LIST='INFO') "; expected "identifier"; SQL statement: 
alter table public_partner drop constraint (select distinct unique_index_name from informa 
tion_schema.constraints where table_name='PUBLIC_PARTNER' and column_list='INFO') [42001-1 
60] 

Come tale vincolo deve essere rimosso in modo corretto?

A proposito:

sql> (select unique_index_name from information_schema.constraints where table_name='PUBLI 
C_PARTNER' and column_list='INFO'); 
UNIQUE_INDEX_NAME 
CONSTRAINT_F574_INDEX_9 
(1 row, 0 ms) 

sembra restituire un output corretto.

risposta

8

Nel linguaggio SQL, i nomi degli identificatori non possono essere espressioni. È necessario eseguire due affermazioni:

select distinct constraint_name from information_schema.constraints 
where table_name='PUBLIC_PARTNER' and column_list='INFO' 

e quindi ottenere il nome identificativo, ed eseguire l'istruzione

ALTER TABLE PUBLIC_PARTNER DROP CONSTRAINT <xxx> 
+0

Grazie, Thomas! Mi aspettavo che tu rispondessi personalmente alla mia domanda :) Il problema è che la tua soluzione è ovvia per me, e accetterò comunque la tua risposta come utile. La cosa brutta è che ho bisogno di automatizzare il mio script delta senza l'intervento manuale: ((( – Alec

+1

con questo ho ottenuto "Vincolo non trovato". Ha funzionato per me con "constraint_name" invece di "unique_index_name", così che la selezione era 'selezionare constraint_name distinto da in formation_schema.constraints dove table_name = 'PUBLIC_PARTNER' e column_list = 'INFO'' Si può anche ulteriormente limitare il tipo di vincolo con l'aggiunta di' e constraint_type =' UNIQUE'' la mia versione H2 era 1.3 .166 btw. – MartinGrotzke

+0

@MartinGrotzke Grazie! Ho aggiornato la mia risposta (c'era anche un errore di battitura in "information_schema"). –

5

Si potrebbe utilizzare una funzione definita dall'utente per eseguire un'istruzione creata dinamicamente. Prima di creare l'alias execute (solo una volta):

CREATE ALIAS IF NOT EXISTS EXECUTE AS $$ void executeSql(Connection conn, String sql) 
throws SQLException { conn.createStatement().executeUpdate(sql); } $$; 

Poi chiamare questo metodo:

call execute('ALTER TABLE PUBLIC_PARTNER DROP CONSTRAINT ' || 
    (select distinct unique_index_name from in formation_schema.constraints 
    where table_name='PUBLIC_PARTNER' and column_list='INFO')); 

... dove execute è la funzione definita dall'utente che esegue un'istruzione.

+1

Questa sarebbe la funzione definita dall'utente:. 'CREATE ALIAS SE NON ESISTE EXECUTE AS $$ vuoto ExecuteSQL (Connection conn, String sql) throws SQLException { conn.createStatement() executeUpdate (sql); } $$; ' – MartinGrotzke

+0

utilizzando questa soluzione ma non funziona con' Funzione non supportata: "VARCHAR +"; Istruzione SQL: '. My Code: 'call execute ('ALTER TABLE DAILY_AGGREGATES DROP CONSTRAINT' + (seleziona distinto nome_collegamento da information_schema.constraints dove table_name = 'DAILY_AGGREGATES' e constraint_type = 'PRIMARY KEY'));' – smajlo

+3

In SQL, il '+' è non usato per concatenare una stringa. Invece, usa '||'. Come in: 'call execute ('ALTER TABLE DAILY_AGGREGATES DROP CONSTRAINT' || (seleziona distinto nome_collegamento da information_schema.vincoli dove table_name = 'DAILY_AGGREGATES' e constraint_type = 'PRIMARY KEY')); ' –