FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
Inserción masiva condicionada
Hola a tod@s.
En un hilo anterior sobre este tema, siguiendo los consejos de Casimiro, logré solucionar mis limitaciones. Por refrescar el tema, os diré que trabajo con Delphi 2010, Firebird 4 y SQL Manager Lite. Tengo que poner un espacio entre : y Campo, porque me salen caras En Firebird tengo la siguiente tabla:
Y el siguiente Procedimiento almacenado:
Y en Delphi tengo el siguiente procedimiento:
La primera inserción la hace bien, pero en la segunda me da el error: 'Attempt to execute an unprepared dynamic SQL statement' Agradeceré vuestra ayuda. |
#2
|
|||
|
|||
Perdonad, pero no he puesto qué es lo que pretendo.
Intento insertar registros en la tabla Charts, pero si existe el registro (todos los campos menos Id y Steps) que en lugar de una inerción se incremente el campo Steps del registro existente. Gracias. |
#3
|
||||
|
||||
Creo que el orden de comprobaciones es incorrecto.
Primero miras si hay que hacer commit. Si has hecho commit, el contador se voverá 0 y harás como si fuera la primera inserción. En tu código, perparabas la sentencia y luego si se trataba de la MaxTenokatesInserteds hacías commit, con lo que ya no está preparada.
|
#4
|
||||
|
||||
De todos modos, creo que lo mejor sería hacer Commit y no CommitRetaining.
Luego, si es la "primera", no tentiendo porqué haces un Rollback. Yo lo haría así, siempre y cuando la transacción no sea compartida por fTexting y otros DataSets.
|
#5
|
||||
|
||||
Aparte de lo indicado por duilioisola, también puedes simplificar el procedure usando "update or insert".
https://firebirdsql.org/refdocs/lang...or-insert.html
__________________
La otra guía de estilo | Búsquedas avanzadas | Etiquetas para código | Colabora mediante Paypal |
#6
|
||||
|
||||
Cita:
|
#7
|
||||
|
||||
Se supone que siempre comprobará la clave primaria, sea de un campo o esté compuesta por más de un campo.
Eso dice la lógica.
__________________
La otra guía de estilo | Búsquedas avanzadas | Etiquetas para código | Colabora mediante Paypal |
#8
|
||||
|
||||
Gracias. Como no conocía la estructura estaba un poco perplejo. Otra cosa: esa instrucción MATCHING, ¿qué hace exactamente? Porque es evidente que lo último (returning) lo que hace es devolver un valor.
|
#9
|
||||
|
||||
MATCHING se refiere a encontrar el registro según los campos que le pasas.
En el ejemplo, busca primero si existe un registro cuyo campo Number es 3278823. Si lo encuentra hace un update sobre ese registro modificando los otros campos que le pasas Name y Location. De lo contrario hace un insert con los tres campos que le pasas. |
#10
|
||||
|
||||
Cita:
|
#11
|
||||
|
||||
Aquí el manual, ya que tiene algo más de juego... por ejemplo, puedes retornar valores OLD.campo o NEW.campo
En firebird 5 tiene más opciones todavía. () |
#12
|
||||
|
||||
Cita:
|
#13
|
||||
|
||||
Cita:
Tengo, por ejemplo, este procedimiento: Código:
CREATE OR ALTER PROCEDURE Act_Libro(Registro SMALLINT, Titulo VARCHAR(60), Autor VARCHAR(60), Genero VARCHAR(25), Situacion VARCHAR(6)) AS DECLARE VARIABLE NewRec SMALLINT; BEGIN UPDATE OR INSERT INTO Titulos (Tipo, Registro, Titulo, Autor, Genero, Situacion) VALUES (3, :Registro, :Titulo, :Autor, :Genero, :Situacion) RETURNING Registro INTO :NewRec; END; Código:
Query->Close(); Query->SQL->Text = "EXECUTE PROCEDURE Act_Libro (:Registro, :Titulo, :Autor, :Genero, :Situacion)"; Query->ParamByName("Titulo")->AsString = Titulo_libro->Text; Query->ParamByName("Autor")->AsString = Autor->Text; Query->ParamByName("Genero")->AsString = Genero_libro->Text; Query->ParamByName("Situacion")->AsString = Situacion_libro->Text; Query->ParamByName("Registro")->AsInteger = this->Tag; Query->ExecSQL(); Query->Transaction->Commit(); |
#14
|
||||
|
||||
Es que estás ejecutando la sentencia dentro de un stored procedure, y en éste no estás devolviendo nada.
__________________
La otra guía de estilo | Búsquedas avanzadas | Etiquetas para código | Colabora mediante Paypal |
#15
|
||||
|
||||
|
#16
|
||||
|
||||
Gracias a los dos; es lo que pasa cuando se tienen errores de base. Pero sigo teniendo la misma duda: ¿cómo trabajo con esa variable en BCB?
|
#17
|
||||
|
||||
Igual que en un SELECT...
No conozco BCB pero supongo que hay algo así como FieldByName(). Código:
Query->Close(); Query->SQL->Text = "EXECUTE PROCEDURE Act_Libro (:Registro, :Titulo, :Autor, :Genero, :Situacion)"; Query->ParamByName("Titulo")->AsString = Titulo_libro->Text; Query->ParamByName("Autor")->AsString = Autor->Text; Query->ParamByName("Genero")->AsString = Genero_libro->Text; Query->ParamByName("Situacion")->AsString = Situacion_libro->Text; Query->ParamByName("Registro")->AsInteger = this->Tag; Query->ExecSQL(); RegistroCreado = Query->FieldByName("newrec")->AsInteger; Query->Transaction->Commit(); |
#18
|
||||
|
||||
Creo que algo así:
EDITO: No había visto el mensaje de [duilioisola].
__________________
La otra guía de estilo | Búsquedas avanzadas | Etiquetas para código | Colabora mediante Paypal |
#19
|
||||
|
||||
Gracias a los dos. Lo probaré y os digo como va.
|
#20
|
||||
|
||||
Pues no: tanto con FieldByName como con ParamByName da error. Con FieldByName me dice Query; Field 'NewRec, not found, y con ParamByName en vez de Field dice que lo no encontrado es el parámetro. He probado a ejecutarlo desde SQL Manager y se ejecuta bien y devuelve un valor coherente, pero no veo como recuperarlo para la aplicación.
|
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Inserción masiva en Firebird | ElDuc | Conexión con bases de datos | 40 | 30-04-2023 11:38:06 |
insercion masiva | Alfredo | Firebird e Interbase | 3 | 12-11-2008 21:34:46 |
Insercion masiva de una BD a otra BD | oscjae | Firebird e Interbase | 5 | 15-12-2006 21:25:49 |
Insercion masiva de registros MUY LENTA | Balda | Firebird e Interbase | 10 | 24-03-2004 22:40:21 |
Inserción masiva en MySQL | Morfo | MySQL | 3 | 09-01-2004 19:05:33 |
|