2012-04-04 30 views
6

Intento eliminar la restricción única para la columna en h2, creada anteriormente como info varchar(255) unique.Eliminando la restricción única para la columna en H2

me trataron:

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'); 

pero sin éxito (como sigue):

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] 

Cómo esta restricción debe ser eliminado correctamente?

Por cierto:

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) 

parece devolver una salida correcta.

Respuesta

8

En el lenguaje SQL, los nombres de los identificadores no pueden ser expresiones. Tiene que ejecutar dos declaraciones:

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

y luego obtener el nombre del identificador, y ejecutar la instrucción

ALTER TABLE PUBLIC_PARTNER DROP CONSTRAINT <xxx> 
+0

Gracias, Thomas! Esperaba que respondiera personalmente a mi pregunta :) El problema es que su solución es obvia para mí, y de todos modos aceptaré su respuesta como útil. Lo malo es que lo necesito para automatizar mi script delta sin intervención manual: ((( – Alec

+1

) Obtuve "Restricción no encontrada". Me funcionó con "constraint_name" en lugar de "unique_index_name", por lo que la selección era 'seleccionar constraint_name distinta de en formation_schema.constraints donde nombre_tabla = 'PUBLIC_PARTNER' y column_list = 'INFO'' Uno puede también restringir adicionalmente el tipo de restricción por agregando' y CONSTRAINT_TYPE =' UNIQUE'' Mi versión H2 fue de 1,3 .166 por cierto – MartinGrotzke

+0

@MartinGrotzke ¡Gracias! He actualizado mi respuesta (también había un error tipográfico en "information_schema"). –

5

Se podría utilizar una función definida por el usuario para ejecutar una instrucción creada dinámicamente. En primer lugar para crear el execute alias (sólo una vez):

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

A continuación, llamar a este método:

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')); 

... donde execute es la función definida por el usuario que ejecuta un comunicado.

+1

Esta sería la función definida por el usuario:. 'CREATE ALIAS SI NO EXISTE EXECUTE AS $$ vacío ExecuteSQL (conn conexión, cadena SQL) throws SQLException { conn.createStatement() executeUpdate (sql); } $$; ' – MartinGrotzke

+0

utilizando esta solución pero está fallando con' Característica no admitida: "VARCHAR +"; Declaración de SQL: '. Mi código: 'call execute ('ALTER TABLE DAILY_AGGREGATES DROP CONSTRAINT' + (seleccione distinct constraint_name from information_schema.constraints donde table_name = 'DAILY_AGGREGATES' y constraint_type = 'PRIMARY KEY'));' – smajlo

+3

En SQL, el '+' es no se usa para concatenar una cuerda. En su lugar, use '||'. Como en: 'call execute ('ALTER TABLE DAILY_AGGREGATES DROP CONSTRAINT' || (seleccione distinct constraint_name from information_schema.constraints donde table_name = 'DAILY_AGGREGATES' y constraint_type = 'PRIMARY KEY')); ' –

Cuestiones relacionadas