En una base de datos de Oracle tengo una clave externa, sin saber su nombre, solo el nombre de la columna y el nombre de la columna de referencia. Quiero escribir una secuencia de comandos SQL que debe caer esta clave externa si es que existe, por lo que este es el código que utilizo:soltar índice o restricción sin saber su nombre para Oracle
declare
fName varchar2(255 char);
begin
SELECT x.constraint_name into fName FROM all_constraints x
JOIN all_cons_columns c ON
c.table_name = x.table_name AND c.constraint_name = x.constraint_name
WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';
end;
La salida de este script es "bloque anónimo completado", por lo que se ha realizado correctamente, pero cuando agrego la parte caída:
declare
fName varchar2(255 char);
begin
SELECT x.constraint_name into fName FROM all_constraints x
JOIN all_cons_columns c ON
c.table_name = x.table_name AND c.constraint_name = x.constraint_name
WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';
if (fName != '') THEN
alter table MY_TABLE_NAME drop constraint fName;
end if;
end;
Entonces consigo éste:
Error report: ORA-06550: line 9, column 5: PLS-00103: Encountered the symbol "ALTER" when expecting one of the following:
begin case declare exit for goto if loop mod null pragma raise return select update while with << close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error. *Action:
Entonces, ¿puede alguien decirme cuál es el problema aquí?
También probé a poner todo en una función:
declare
function getFName return varchar2 is
fName varchar2(255 char);
begin
SELECT x.constraint_name into fName FROM all_constraints x
JOIN all_cons_columns c ON
c.table_name = x.table_name AND c.constraint_name = x.constraint_name
WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';
return fName;
end;
begin
if getFName() != '' then
alter table all_events drop constraint getFName();
end if;
end;
El resultado fue el mismo error causado por la declaración "alter table"
Este también no ayudó:
alter table all_events drop constraint
(SELECT x.constraint_name into fName FROM all_constraints x
JOIN all_cons_columns c ON
c.table_name = x.table_name AND c.constraint_name = x.constraint_name
WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME');
La salida fue:
Error report: SQL Error: ORA-02250: missing or invalid constraint name 02250. 00000 - "missing or invalid constraint name" *Cause: The constraint name is missing or invalid. *Action: Specify a valid identifier name for the constraint name.
Para un servidor sql (MS SQL) es tan fácil hacer esto. Simplemente declarando una variable con @ y la configuró, después de eso solo úsala. En Oracle no tengo idea de lo que no está funcionando ...
Hey simplemente una cuestión adicional acerca de esto: Con esta instrucción de selección teórico me gustaría tener más de un nombre de restricción si una columna C1 de las referencias de la tabla A1 a C2 de la tabla A2 y referencias C1 a C3 de la tabla A3, entonces obtendría los nombres para C1-> C2 y C1-> C3, entonces la pregunta es ¿dónde puedo unir la información a qué columna soy referenciando? – radio
@radio: On 'all_constraints',' (r_owner, r_constraint_name) 'es efectivamente una clave externa; puede volver a unirse a 'all_constraints' para obtener información sobre la (s) columna (s) referenciada (s). (Dentro de Oracle, una clave externa se implementa como una clave externa a * otra restricción *. Esto tiene sentido si se tiene en cuenta lo que el DBMS debe hacer para aplicar una restricción de clave externa.) – ruakh
@radio: Por cierto, su preocupación "teórica" me preocupa un poco, porque hay otros problemas más grandes con su código: por ejemplo, usa 'all_constraints' y' all_cons_columns' sin verificar 'owner' , y no verifica para asegurarse de que ''MY_COLUMN_NAME'' sea la única columna en la clave externa. Entonces, tu parte de código no es de propósito general. Asumía que planeabas usarlo en una circunstancia específica en la que tenías mucha otra información, pero por algún motivo, simplemente, faltabas el nombre de restricción. Si necesita un código de propósito general, tiene que arreglar muchas cosas. – ruakh