Ir al contenido


Foto

[RESUELTO] sintaxis: procedimiento almacenado en flamerobin firebird


  • Por favor identifícate para responder
16 respuestas en este tema

#1 dant

dant

    Member

  • Miembros
  • PipPip
  • 12 mensajes

Escrito 23 julio 2010 - 10:55

Hola a todos; soy nuevo en este foro y estoy recien aprendiendo transact sql. El problema es que estoy tratando de hacer un procedimiento almacenado que me permita ingresar datos a una tabla pero antes comprobar ( a través del ID ) que este registro no exista. El código es:



sql
  1. SET TERM ^ ;
  2.  
  3. CREATE PROCEDURE IngresarPer
  4. (codper CHAR(5), apeper VARCHAR(25), nomper VARCHAR(25), dniper CHAR(8), fnacper DATE, dirper VARCHAR(30), provper VARCHAR(25),
  5. telfper VARCHAR(12), celper VARCHAR(16), emailper VARCHAR(30), cargper VARCHAR(25), fingper DATE, fcesper DATE, plaper CHAR(1),
  6. fondpensper VARCHAR(25), codessper VARCHAR(15))
  7. AS
  8. BEGIN
  9.     IF (SELECT * FROM REGISTROSPER WHERE REGISTROSPER.COD_PER = codper) IS NULL THEN
  10.         INSERT INTO REGISTROSPER VALUES (codper, apeper, nomper, dniper, fnacper, dirper, provper, telfper, celper,
  11. emailper, cargper, fingper, fcesper, plaper, fondpensper, codessper);
  12.     END IF;
  13. END^
  14.  
  15. SET TERM ; ^



Al ejecutarlo me detecta errores de sintaxis.

Agradesco su aporte.
  • 0

#2 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.484 mensajes
  • LocationMallorca

Escrito 23 julio 2010 - 11:05

Hola.

Hace muchos años que no trabajo con Transact-SQL, pero realmente la línea del condicional tiene muy mal aspecto, mejor cámbiala por :

IF (SELECT COUNT(*) FROM REGISTROSPER WHERE REGISTROSPER.COD_PER = codper) = 0 THEN

Saludos.
  • 0

#3 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.484 mensajes
  • LocationMallorca

Escrito 23 julio 2010 - 11:07

Por cierto, ¿ no te dice el error de sintaxis que tiene el procedimiento almacenado ?, ¿ no te marca la fila y columna donde se encuentra ese error ?.
  • 0

#4 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.469 mensajes
  • LocationMéxico

Escrito 23 julio 2010 - 11:08

Bienvenido a DelphiAccess dant

Creo que te falta la palabra reservada RETURNS



sql
  1. SET TERM ^ ;
  2.  
  3. CREATE PROCEDURE IngresarPer
  4. RETURNS (codper CHAR(5), apeper VARCHAR(25), nomper VARCHAR(25), dniper CHAR(8), fnacper DATE, dirper VARCHAR(30),
  5. provper VARCHAR(25), telfper VARCHAR(12), celper VARCHAR(16), emailper VARCHAR(30), cargper VARCHAR(25), fingper DATE,
  6. fcesper DATE, plaper CHAR(1), fondpensper VARCHAR(25), codessper VARCHAR(15))
  7. AS
  8. BEGIN
  9.     IF (SELECT * FROM REGISTROSPER WHERE REGISTROSPER.COD_PER = codper) IS NULL THEN
  10.         INSERT INTO REGISTROSPER VALUES (codper, apeper, nomper, dniper, fnacper, dirper, provper, telfper, celper,
  11. emailper, cargper, fingper, fcesper, plaper, fondpensper, codessper);
  12.     END IF;
  13. END^
  14.  
  15. SET TERM ; ^



Salud OS
  • 0

#5 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 23 julio 2010 - 11:13

Hola a todos; soy nuevo en este foro y estoy recien aprendiendo transact sql. El problema es que estoy tratando de hacer un procedimiento almacenado que me permita ingresar datos a una tabla pero antes comprobar ( a través del ID ) que este registro no exista.


Saludos.

Creo que si posteas en la sección Firebird te estarás refiriendo al PSQL que es como se le llama en Firebird (espero no equivocarme).

Yo haría:


sql
  1. IF (NOT EXISTS(SELECT 1 FROM MITABLA WHERE MICAMPO = MIVALOR)) THEN
  2. --Realizo el insert



Por cierto, no indicas que versión de Firebird estas utilizando.
  • 0

#6 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 23 julio 2010 - 11:16

Saludos.

Viendo nuevamente tú código no es necesario poner END IF. Esa clausula no existe en Firebird.

Debes de poner solamente END si tienes un BEGIN.
  • 0

#7 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.484 mensajes
  • LocationMallorca

Escrito 23 julio 2010 - 11:49

La subconsulta del condicional va a dar problemas seguro, ya que no es una consulta singleton (se llama así, ¿ verdad ?), no devuelve un valor único que se pueda comparar con NULL sino que devuelve un dataset, un conjunto indeterminado de filas con varios campos.

IF (SELECT * FROM REGISTROSPER WHERE REGISTROSPER.COD_PER = codper) IS NULL THEN

Por eso hay que cambiarla por una subconsulta singleton

IF (SELECT COUNT(*) FROM REGISTROSPER WHERE REGISTROSPER.COD_PER = codper) = 0 THEN

Aparte de eso, que más bien lo detectaría en tiempo de ejecución que de compilación, probablemente hay otros errores de sintaxis.

A ver de que versión de SQL Server o Firebird se trata.

  • 0

#8 dant

dant

    Member

  • Miembros
  • PipPip
  • 12 mensajes

Escrito 23 julio 2010 - 03:07

Versión de firebird: 2.1.3

Muchas gracias a todos por responder; resolví varias dudas he modificado el código pero aún me sigue botando error:


Código modificado:




sql
  1. SET TERM ^ ;
  2.  
  3. CREATE PROCEDURE IngresarPer
  4. RETURNS (codper CHAR(5), apeper VARCHAR(25), nomper VARCHAR(25), dniper CHAR(8), fnacper DATE, dirper VARCHAR(30), provper VARCHAR(25), telfper VARCHAR(12), celper VARCHAR(16), emailper VARCHAR(30), cargper VARCHAR(25), fingper DATE, fcesper DATE, plaper CHAR(1), fondpensper VARCHAR(25), codessper VARCHAR(15))
  5. AS
  6. BEGIN
  7.     IF (SELECT COUNT(*) FROM REGISTROSPER WHERE REGISTROSPER.COD_PER = codper) = 0 THEN
  8.         INSERT INTO REGISTROSPER VALUES (codper, apeper, nomper, dniper, fnacper, dirper, provper, telfper, celper, emailper, cargper, fingper, fcesper, plaper, fondpensper, codessper);
  9.     END
  10. END^
  11.  
  12. SET TERM ; ^


Mensaje de Error:

Message: isc_dsql_prepare failed

SQL Message : -104
Invalid token

Engine Code    : 335544569
Engine Message :
Dynamic SQL Error
SQL error code = -104
Token unknown - line 7, column 9
SELECT

Muchas gracias por su aporte.
  • 0

#9 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.469 mensajes
  • LocationMéxico

Escrito 23 julio 2010 - 03:22

Hola

Viendo mas detenidamente creo que el RETURNS no viene al caso porque son datos de entrada (mi error, perdón :( ).

Salud OS
  • 0

#10 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.469 mensajes
  • LocationMéxico

Escrito 23 julio 2010 - 03:24

Por otro lado (espero no volverme a equivocar)

No le hacen falta los ':' en los valores ?



sql
  1. IF (SELECT COUNT(*) FROM REGISTROSPER WHERE REGISTROSPER.COD_PER = :codper) = 0 THEN
  2. VALUES (:codper, :apeper, :nomper, :dniper, :fnacper, :dirper, :provper, :telfper, :celper, :emailper, :cargper,
  3.             :fingper, :fcesper, :plaper, :fondpensper, :codessper)



Salud OS
  • 0

#11 dant

dant

    Member

  • Miembros
  • PipPip
  • 12 mensajes

Escrito 23 julio 2010 - 04:17

No te preocupes egostar aquí estamos para aprender; pero aún sigo con mi problema.

Agradesco su aporte.
  • 0

#12 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.484 mensajes
  • LocationMallorca

Escrito 23 julio 2010 - 04:50

Hola.

No estoy seguro de que puedas poner una subconsulta dentro de la expresión de un IF. Pero en el caso de que se pueda, la expresión a evaluar del IF debe ir encerrada en paréntesis. Es decir :



sql
  1. SET TERM ^ ;
  2.  
  3. CREATE PROCEDURE IngresarPer
  4. (codper CHAR(5), apeper VARCHAR(25), nomper VARCHAR(25), dniper CHAR(8), fnacper DATE, dirper VARCHAR(30), provper VARCHAR(25), telfper VARCHAR(12), celper VARCHAR(16), emailper VARCHAR(30), cargper VARCHAR(25), fingper DATE, fcesper DATE, plaper CHAR(1), fondpensper VARCHAR(25), codessper VARCHAR(15))
  5. AS
  6. BEGIN
  7.     IF ((SELECT COUNT(*) FROM REGISTROSPER WHERE REGISTROSPER.COD_PER = :codper) = 0) THEN BEGIN
  8.         INSERT INTO REGISTROSPER VALUES (:codper, :apeper, :nomper, ;dniper, :fnacper, :dirper, :provper, :telfper, :celper, :emailper, :cargper, :fingper, :fcesper, :plaper, :fondpensper, :codessper);
  9.     END
  10. END^
  11.  
  12. SET TERM ; ^


Pero realmente creo que no puedes hacerlo así, directamente. Por lo que la solución pasar por poner el resultado de la subconsulta en una variable, antes de evaluar la expresión en el IF, es decir :



sql
  1. SET TERM ^ ;
  2.  
  3. CREATE PROCEDURE IngresarPer
  4. (codper CHAR(5), apeper VARCHAR(25), nomper VARCHAR(25), dniper CHAR(8), fnacper DATE, dirper VARCHAR(30), provper VARCHAR(25), telfper VARCHAR(12), celper VARCHAR(16), emailper VARCHAR(30), cargper VARCHAR(25), fingper DATE, fcesper DATE, plaper CHAR(1), fondpensper VARCHAR(25), codessper VARCHAR(15))
  5. AS
  6. DECLARE variable existe SMALLINT;
  7. BEGIN
  8.     SELECT COUNT(*) FROM REGISTROSPER WHERE REGISTROSPER.COD_PER = :codper INTO :existe;
  9.  
  10.     IF (:existe = 0) THEN BEGIN
  11.         INSERT INTO REGISTROSPER VALUES (:codper, :apeper, :nomper, ;dniper, :fnacper, :dirper, :provper, :telfper, :celper, :emailper, :cargper, :fingper, :fcesper, :plaper, :fondpensper, :codessper);
  12.     END
  13. END^
  14.  
  15. SET TERM ; ^


NOTA: Las variables en Firebird siempre van precedidas por el símbolo de dos puntos, en el cuerpo del procedimiento almacenado. Y la cláusula RETURNS se utiliza para designar los parámetros de salida del procedimiento almacenado, pero en este caso los parámetros que declaras son los de entrada, por lo tanto no van detrás de un RETURNS. Y finalmente las instrucciones dentro de un IF (o de cualquier otra agrupación) van dentro de un BEGIN ... END.

Estoy escribiendo esto de memoria, no tengo ningún Firebird a mano para probarlo, así que es posible de que te salten otros errores. Simplemente dinos cuales son, y los resolveremos.

Saludos.
  • 0

#13 dant

dant

    Member

  • Miembros
  • PipPip
  • 12 mensajes

Escrito 24 julio 2010 - 11:24

Muchas gracias Marc y a todos los que aportarón ideas el procedimiento funciona correctamente.
  • 0

#14 dant

dant

    Member

  • Miembros
  • PipPip
  • 12 mensajes

Escrito 24 julio 2010 - 11:26

Me olvidava de algo [RESUELTO] jejeje. :wink:
  • 0

#15 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.469 mensajes
  • LocationMéxico

Escrito 24 julio 2010 - 11:34

Me olvidava de algo [RESUELTO] jejeje. :wink:


Hola Dant, que bien que ya se reolvió tu problema.

¿ Podrías colocar la solución final para futuras consultas ?

Salud OS
  • 0

#16 dant

dant

    Member

  • Miembros
  • PipPip
  • 12 mensajes

Escrito 24 julio 2010 - 12:01

Claro que si egostar:



sql
  1. SET TERM ^ ;
  2. CREATE PROCEDURE INGRESARPER (
  3.     CODPER CHAR(5),
  4.     APEPER VARCHAR(25),
  5.     NOMPER VARCHAR(25),
  6.     DNIPER CHAR(8),
  7.     FNACPER DATE,
  8.     DIRPER VARCHAR(30),
  9.     PROVPER VARCHAR(25),
  10.     TELFPER VARCHAR(12),
  11.     CELPER VARCHAR(16),
  12.     EMAILPER VARCHAR(30),
  13.     CARGPER VARCHAR(25),
  14.     FINGPER DATE,
  15.     FCESPER DATE,
  16.     PLAPER CHAR(1),
  17.     FONDPENSPER VARCHAR(25),
  18.     CODESSPER VARCHAR(15) )
  19. AS
  20. DECLARE variable existe SMALLINT;
  21. BEGIN
  22.     SELECT COUNT(*) FROM REGISTROSPER WHERE REGISTROSPER.COD_PER = :codper INTO :existe;
  23.     IF (:existe = 0) THEN BEGIN
  24.         INSERT INTO REGISTROSPER VALUES (:codper, :apeper, :nomper, :dniper, :fnacper, :dirper, :provper, :telfper, :celper, :emailper, :cargper,
  25.                 :fingper, :fcesper, :plaper, :fondpensper, :codessper);
  26.     END
  27. END^
  28. SET TERM ; ^



(y)
  • 0

#17 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.469 mensajes
  • LocationMéxico

Escrito 24 julio 2010 - 12:03

Ah que bien, gracias (y)

Salud OS
  • 0




IP.Board spam blocked by CleanTalk.