Error PLS-00306 al llamar al cursor
Pregunta
Creo que me falta algo aquí.Aquí está la parte relevante del disparador:
CURSOR columnNames (inTableName IN VARCHAR2) IS
SELECT COLUMN_NAME FROM USER_TAB_COLUMNS WHERE TABLE_NAME = inTableName;
/* Removed for brevity */
OPEN columnNames('TEMP');
Y aquí está el mensaje de error que recibo,
27/20 PLS-00306: wrong number or types of arguments in call to 'COLUMNNAMES' 27/2 PL/SQL: Statement ignored
Si entiendo la documentación correctamente, debería funcionar, pero como no es así, debo estar haciendo algo mal.¿Algunas ideas?
@Mateo - Agradezco la ayuda, pero la razón por la que estoy confundido es porque este fragmento de código no me funciona y genera los errores mencionados.Tenemos otros activadores en la base de datos con un código casi exactamente igual, así que no estoy seguro de si es algo que hice mal o algo relacionado con la forma en que estoy tratando de almacenar el activador, etc.
@Mateo - Bueno, ahora me da vergüenza.Copié y pegué el código que proporcionaste en un nuevo activador y funcionó bien.Así que volví al disparador original, lo probé y recibí el mensaje de error nuevamente, excepto que esta vez comencé a eliminar cosas del disparador y después de deshacerme de esta línea,
FOR columnName IN columnNames LOOP
Las cosas se salvaron bien.Entonces resulta que donde pensé que estaba el error, en realidad no estaba donde estaba el error.
Solución
@Robar
Si cortas/pegas el código que tengo aquí, ¿funciona?
¿Cómo/dónde llamas a tu código?Está en un gatillo, ¿verdad?
La consulta que ha escrito aquí es en realidad el código que produce el error, o simplemente un ejemplo (por ejemplo, ¿puede reproducir el error con la consulta que tiene arriba)?
Otros consejos
Para aclarar la causa del problema.Como dices
OPEN columnNames('TEMP');
trabajó mientras
FOR columnName IN columnNames LOOP
No.La declaración FOR funcionaría bien si también incluyera el parámetro así:
FOR columnName IN columnNames('TEMP') LOOP
No muestra el código donde obtiene las filas, por lo que no puedo decir su propósito, pero donde trabajo, OPEN se usa comúnmente para recuperar la primera fila (en este caso, el nombre de la primera columna de la tabla dada) mientras que el FOR se utiliza para recorrer todas las filas devueltas.
@Comentario de Rob.No puedo comentar, así que actualizo aquí.El parámetro que falta es lo que describo arriba.Agregó una respuesta indicando que simplemente eliminó el bucle FOR.En ese momento no parecía que usted entendiera por qué eliminarlo marcaba la diferencia.Es por eso que intenté explicarlo ya que, según sus necesidades, el bucle FOR podría ser una mejor solución.
Funciona bien para mí.
create or replace procedure so_test_procedure as
CURSOR columnNames (inTableName IN VARCHAR2) IS
SELECT COLUMN_NAME FROM USER_TAB_COLUMNS WHERE TABLE_NAME = inTableName;
BEGIN
OPEN columnNames('TEMP');
CLOSE columnNames;
END;
procedure so_test_procedure Compiled.
execute so_test_procedure();
anonymous block completed