PDA

Ver la Versión Completa : Stored Procedure para insertar campos


jafera
16-07-2013, 16:37:54
Buenas a todos.

En un hilo anterior me enseñasteis como hacer un update a una tabla destino con los datos de una tabla origen utilizando un stored procedure, un proceso que realizado con locate y sql tardaaaaaa.....aaaaba mucho se hace en un plis plas.

Ahora necesito saber como lo tengo que hacer para insertar los datos de la tabla origen que no esten en la tabla destino con el mismo sistema debido a su velocidad de vertigo, (parece el AVE).

Lo que realizo es un update si DNI=DNI y COD_CAT=COD_CAT ya que una persona puede tener dos licencias con el mismo DNI pero diferente COD_CAT (codigo categoria).

Una vez la tabla tiene datos el update comprueba DNI y COD_CAT y si lo encuentra, pues lo actualiza, pero si no lo encuentra necesito añadirlo.

Algún maestro del sql me puede echar un cable?

No se de que manera puedo saber antes del insert que datos existen y que datos no, aquí mi GRAN duda.

Saludos

Josep

Casimiro Notevi
16-07-2013, 17:29:34
Aclara un poco más los campos y lo que quieres hacer.

jafera
16-07-2013, 17:58:34
Gracias Antonio

He querido retomar un poco el hilo del 2011 en el que al final me querias comprar un velero, jejeje...

Pues como decia antes tengo una tabla nacional origen de los datos con campos varchar excepto un integer campos C1, C2, C3, C4...C14, esta tabla la lleno con datos procedentes de un fichero txt que me envian semanalmente, este tema tambien lo comentamos hace unas semanas y funciona a la perfección, luego tengo una tabla origen autonomica que se llena con el mismo sistema.

Despues debo pasar los datos primero de la tabla nacional a la tabla destino con campos varchar nombre, apellido1, apellido2, etc codigo categoria integer.

Si la tabla destino que es tabla sobre la cual trabajo, tiene datos entrados, pues el stored procedure me los actualiza en un santiamen, pero si el corredor no esta en la tabla ya que es nuevo de esta semana, debo insertarlo.

Ademas una vez hecho esto debo insertar los datos procedentes de las tablas autonomicas que no existan en la tabla principal.

El motivo es que las licencias de corredores las emite la RFEC pero las autonomias, emiten unas licencias validas solo en la región correspondiente para carreras locales, un corredor con licencia autónoma vasca no puede participar en carreras andaluzas, por ejemplo y evidentemente estos datos autonómicos no figuran en las tablas RFEC, por esos se deben añadir.

Aquí mi problema.

No se si se entiende bien el problema, antes yo hacia la actualización con locate y sql y me podia ir a comer mientras el proceso estaba en marcha, una vez implantado el update con procedimeiento almacenado el tiempo de actualización es casi imperceptible de ahí que me gustaría hecer los insert con un sistema parecido.

Este es el codigo del procedure para actualizar:


COMMIT WORK;
SET AUTODDL OFF;
SET TERM ^ ;
/* Stored procedures */
CREATE PROCEDURE "ACTUALITZA_REFC"
AS
BEGIN EXIT; END ^

ALTER PROCEDURE "ACTUALITZA_REFC"
AS
declare variable DNI VARCHAR(12) CHARACTER SET ISO8859_1;
declare variable LLICENCIA VARCHAR(14) CHARACTER SET ISO8859_1;
declare variable NOM VARCHAR(20) CHARACTER SET ISO8859_1;
declare variable COGNOM1 VARCHAR(25) CHARACTER SET ISO8859_1;
declare variable COGNOM2 VARCHAR(25) CHARACTER SET ISO8859_1;
declare variable CODIUCI VARCHAR(12) CHARACTER SET ISO8859_1;
declare variable CODI_CAT INTEGER;
declare variable CLUB VARCHAR(25) CHARACTER SET ISO8859_1;
declare variable PUBLICITAT VARCHAR(25) CHARACTER SET ISO8859_1;
begin
FOR SELECT C11, C10, C5, C6, C7, C8, C13, C14, C16
FROM CTR0003E
INTO :DNI, :LLICENCIA, :NOM, :COGNOM1, :COGNOM2, :CODI_CAT, :CODIUCI, :CLUB, :PUBLICITAT
DO BEGIN
UPDATE CTR0003 SET
LLICENCIA=:LLICENCIA,
NOM=:NOM,
COGNOM1=:COGNOM1,
COGNOM2=:COGNOM2,
CODIUCI=:CODIUCI,
CODI_CAT=:CODI_CAT,
CLUB=:CLUB,
PUBLICITAT=:PUBLICITAT
WHERE DNI = :DNI AND CODI_CAT=:CODI_CAT;
END
end
^
SET TERM ; ^
COMMIT WORK;
SET AUTODDL ON;

Saludos

Casimiro Notevi
16-07-2013, 18:57:27
Perdona, pero esta calor no me deja pensar bien :o
El caso es que no acabo de entender exactamente el proceso.
¿Tienes los datos de los ciclistas en una tabla y quieres insertarlo en otra distinta?

jafera
16-07-2013, 19:28:55
Mas o menos.

Explico el proceso:

1- Obtengo el txt nacional y lo cargo en una tabla temporal de firebird
2- Obtengo los txt autonomicos y los cargo en unas tablas temporales (una por autonomia) ya que los datos pueden variar en su formato
3- Paso los datos de la tabla temporal nacional a la tabla general de trabajo
4- Paso los datos de las tablas autonomicas a la tabla principal de trabajo, es decir quiero añadir los corredores que no tienen licencia nacional pero si autonómica.

Los pasos 3 y 4 es donde demoro mucho tiempo en actualizar, si la tabla tiene datos pues estos se actualizan sin problema con el stored procedure, pero si los datos no existen se deben añadir y no se como hacerlo.

He dudado en si seria mejor borrar toda la tabla principal y hacer un insert masivo de los datos nacionales y luego solo insertar los autonomicos que no figuren en la misma, pero estoy en el mismo punto de inflexión, no se como ejecutar estos procesos sin un update con sql el cual me lleva mucho tiempo en realizarse.

Gracias de nuevo

Josep

Casimiro Notevi
16-07-2013, 19:44:31
Seguramente lo más rápido es borrar la "nacional" y luego hacer inserts de las "autonómicas". Te ahorras buscar en cada uno y actualizar en los que ya existen.

Puedes hacer un select de todas las tablas "autonómicas" con inner join y luego un insert, por ejemplo, algo parecido a esto:

delete from tbNacionales;

for select *
from tbAndalucia ...
inner join tbExtremadura ...
inner join tbGalicia ...
...
into dato1, dato2, dato3, dato4, dato5, ...
do
begin
insert into tbNacionales values (:dato1,:dato2,:dato3,...)
end

Casimiro Notevi
16-07-2013, 19:49:00
He querido retomar un poco el hilo del 2011 en el que al final me querias comprar un velero, jejeje...
Eso está ahora bastante lejos de mis posibilidades :(
Pero no pierdo la esperanza :rolleyes:, de momento tengo ya titulación :)

jafera
16-07-2013, 19:55:29
Eso es importante, yo to tampoco tengo barco pero si título, ya se sabe en casa del herrero cuchara de palo.:(:(

Casimiro Notevi
16-07-2013, 20:19:28
Eso es importante, yo to tampoco tengo barco pero si título, ya se sabe en casa del herrero cuchara de palo.:(:(
Habrá que esperar algún buen chollo, o una lotería, lo que llegue primero :D

jafera
16-07-2013, 20:33:03
Seguramente lo más rápido es borrar la "nacional" y luego hacer inserts de las "autonómicas". Te ahorras buscar en cada uno y actualizar en los que ya existen.


Gracias de nuevo.

Esto seria ideal si se recibieran todas las autonomias, pero habitualmente cada una trabaja con la tabla nacional más la tabla de su autonomía como máximo la vecina.

Sigo dandole vueltas ya que me guste o no debo basarme en la tabla nacional que es la maestra, la que recoge la gran mayoria de practicantes del ciclismo y luego complementarla con la de la autonomía (cada usuario basicamente la suya).

Si cada semana borro la tabla general y la recargo con la llegada del nuevo txt, tengo la tabla nacional al dia pero luego debo añadir los datos autonomicos, no se que es lo más rápido si un borrado y un insert o un update.

La tabla nacional actualmente gira por los 60.000 registros y el update tarda unos 3 o 4 minutos.

No se a mi el calor puede que tampoco me deje pensar, esto unido a mi falta de experiencia en estos menesters sql pues me deja bastante bajo de moral y a punto de abandonar el barco, este proyecto ya ha estado mucho tiempo en dique seco por este problema y ahora lo he querido retomar despues del campeonato de España, pero creo que lo aparcaré de nuevo hasta el año próximo antes del nuevo campeonato pues me veo completamente ofuscado y vencido por el Sr. SQL.

En mi negocio tengo tambien un sistema realizado en delphi corriendo en FB 1.5 y hay procesos parecidos que se realizan en un tiempo prudencial. Este es que me saca de quicio y creo que debe haber un sistema para efectuar estos inserts o updates más rápidos, hasta un programa de carreras que usamos hecho con VB y tablas access es más rápido y los datos a procesar son los mismos origenes (txt).

No se lo dejaré por hoy y mañana será otro dia.

Gracias y saludos

Josep

Casimiro Notevi
16-07-2013, 20:40:10
Hombre, si quieres más precisión, entonces mejor danos información de las tablas implicadas.
Y recuerda que con firebird también tienes la sentencia: update or insert (http://www.firebirdsql.org/refdocs/langrefupd25-update-or-insert.html)
No abandones el barco, eso es lo último, ya sabes ;)

jafera
17-07-2013, 10:42:30
Bunos dia a todos.

Gracias por los ánimos, no voy a abandonar el barco, soy el capitán y me hundo con él, jejeje...

Siguiendo con el problema paso a detallar la creación de las tablas:

Tabla temporal donde cargo el archivo txt nacional (a dia de hoy +o- 60.000 registros)


CREATE TABLE "CTR0003E"
(
"C1" VARCHAR(1) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C2" VARCHAR(1) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C3" VARCHAR(1) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C4" VARCHAR(1) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C5" VARCHAR(25) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C6" VARCHAR(25) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C7" VARCHAR(20) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C8" VARCHAR(3) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C9" VARCHAR(3) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C10" VARCHAR(12) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C11" VARCHAR(12) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C12" VARCHAR(2) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C13" VARCHAR(12) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C14" VARCHAR(30) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C15" VARCHAR(3) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C16" VARCHAR(25) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C17" VARCHAR(15) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C18" VARCHAR(15) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C19" VARCHAR(15) CHARACTER SET ISO8859_1 COLLATE ES_ES
);


Tabla temporal donde cargo el archivo txt autonomico, (a dia de hoy +o- 20.000 registros de los que muchos estan en el txt nacional)


CREATE TABLE "CTR0003C"
(
"C1" VARCHAR(3) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C2" VARCHAR(20) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C3" VARCHAR(25) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C4" VARCHAR(25) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C5" VARCHAR(20) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C6" VARCHAR(3) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C7" VARCHAR(14) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C8" VARCHAR(12) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C9" VARCHAR(25) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C10" VARCHAR(3) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C11" VARCHAR(25) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"C12" VARCHAR(12) CHARACTER SET ISO8859_1 COLLATE ES_ES
);


Tabla destino donde debo insertar o actualizar los datos procedentes primero de la nacional y luego los que no existan de la autonomica


CREATE TABLE "CTR0003"
(
"ID_CORREDOR" INTEGER NOT NULL,
"DORSAL" INTEGER,
"DORSAL2" INTEGER,
"COGNOM1" VARCHAR(25) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"COGNOM2" VARCHAR(25) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"NOM" VARCHAR(20) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"CODI_CAT" INTEGER,
"NACIO" VARCHAR(3) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"LLICENCIA" VARCHAR(14) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"DNI" VARCHAR(12) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"CODIUCI" VARCHAR(12) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"CODI_CLUB" INTEGER,
"CLUB" VARCHAR(25) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"ABR_CLUB" VARCHAR(3) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"PUBLICITAT" VARCHAR(25) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"SEXE" VARCHAR(1) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"FEDERAT" VARCHAR(1) CHARACTER SET ISO8859_1 COLLATE ES_ES,
"DATA_NAIX" DATE,
"EDAT" INTEGER,
"CATEGORIA" VARCHAR(5) CHARACTER SET ISO8859_1 COLLATE ES_ES
);


A ver si así se puede ver de una forma más clara que proceso debo realizar para llenar esta tabla CTR0003 con los datos de CTR0003E y luego con los que no estén en CTR0003E de CTR0003C

Saludos y gracias por vuestro tiempo

Josep

fjcg02
17-07-2013, 11:56:25
Hola jafera,

yo lo haría de un sólo paso...

1.- Ya has cargado la tabla temporal de los datos nacionales...

Ahora, inserta los de la tabla autonómica que no estén en la nacional:

insert into "CTR0003"
( "ID_CORREDOR" , "DORSAL" , "DORSAL2" , "COGNOM1" , "COGNOM2" , "NOM" , "CODI_CAT" , "NACIO" , "LLICENCIA" , "DNI" ,, "CODIUCI" , "CODI_CLUB" , "CLUB" , "ABR_CLUB" , "PUBLICITAT", "SEXE" , "FEDERAT" , "DATA_NAIX" , "EDAT" , "CATEGORIA" )
SELECT C1, C2, C3... FROM "CTR0003C" AUTONOMICA
LEFT JOIN "CTR0003" DEFINITIVA ON ( AUTONOMICA.DNI= DEFINITIVA.DNI )
WHERE DEFINITIVA.DNI IS NULL

Observa la segunda parte "SELECT ... LEFT JOIN ...
Si ejecutas esto en el ibexpert por ejemplo, incluyes el DNI de la tabla definitiva en la select ( DEFINITIVA.DNI) y quitas la where, te saldrán todos los registros de la tabla autonomica, y el DNI de los que que encuentre en la tabla nacional. Aquellos cuyo DNI de la tabla definitiva están vacíos son los que no encuentra en la tala definitiva. Si incluyes la clausula "WHERE DEFINITIVA.DNI IS NULL" le estás diciendo que sólo te devuelva los registros que están en la tabla autonomica y no en la definitiva. Una vez que hayas hecho esas comprobaciones, ejecuta toda la sentencia.
Inserta en la tabla definitiva todos los registros que devuelva la select que te digo. Si afinas con la select, todo en un solo paso.

Ten en cuenta que el orden de los campos en la select son importantes, ya que se cargan en el mismo orden que has puesto en la INSERT. Es decir, si en primer campo de la insert es el DNI, en la select el primer campo debe ser el DNI. ( no especificas el significado de los capos C1, C2, ...).
También ten en cuenta que la condición del where puede ser diferente ( no conozco en detalle las tablas) y por lo que comentas interviene algún campo más.

Te dejo de deberes que hagas lo siguiente:
1.- Jugar con la select hasta que te salgan los registros que necesites, así como la información que necesites ( campos en orden correcto).
2.- Ver la diferencia entre el INNER JOIN y el LEFT JOIN.
3.- Hacer la inserción ( que te tardará 15 segundos máximo).

Prueba y nos cuentas.

Un saludo

jafera
17-07-2013, 12:28:26
Gracias por la nueva ayuda en cuanto tenga un minuto lo pruebo.

Para la clausula where, intervienen dos campos DNI y COD_CAT pues como comenté anteriormente en otro post, una persona (DNI) puede tener dos categorias (COD_CAT), por ejemplo un comisario (yo) puedo tener licencia de comisario y de cicloturista a la vez, con lo cual aparezco dos veces en la tabla.

Repito busco unos minutos de tranquilidad y pruebo, esto de los join no lo tengo muy por mano y veo que puede ser interesante, ya que lo que haré es borrar toda la tabla definitiva antes del insert y hacer un insert masivo en vez de actualizar registros y luego añadir si no existen.

Por cierto es correcto para hacer el left join colocar el código así?:


LEFT JOIN "CTR0003" DEFINITIVA ON ( AUTONOMICA.DNI= DEFINITIVA.DNI and AUTONOMICA.COD_CAT= DEFINITIVA.COD_CAT)


Si es correcto luego en la clausula WHERE tendré que poner lo mismo, no?

Gracias de nuevo

Josep

Casimiro Notevi
17-07-2013, 12:54:07
Si es correcto luego en la clausula WHERE tendré que poner lo mismo, no?
No :)
El inner sirve para enlazar las distintas tablas con sus campos relacionados.
El where es para filtrar (aunque con los filtros también se puede "enlazar")

fjcg02
17-07-2013, 12:56:52
Sí,

a esto se le llaman alias. Cuando cruzas dos tablas, pueden tener campos con el mismo nombre. Para que el motor sepa al campo de qué tabla te refieres, debes especificarle o el nombre de la tabla, o el alias que le hayas puesto.


Select Tabla1.DNI, Tabla2.DNI FROM Tabla1
INNER join Tabla2 ON (Tabla1.DNI = Tabla2.DNI)
Where Tabla2.DNI = '99999'

es lo mismo que

Select T1.DNI, T2.DNI FROM Tabla1 T1
INNER join Tabla2 T2 ON (T1.DNI = T2.DNI)
Where T2.DNI = '99999'


A ver si tienes suerte. Juega con las select primero hasta que te devuelva los registros que quieras con la información que necesites. Luego ya tetiras por la inserción.

Respecto a la información, no la tienes demasiado normalizada, ya que supongo que repites información de una persona por categoría. Para normalizarla tendrías que tener una tabla de personas, y otra de categorías en las que está federado cada persona, con las consiguientes relaciones entre las tablas. Lo que ocurre es que esto te "complica" la gestión ya que tienes que manejar más tablas y relaciones entre ellas, y puede que eso no sea lo que más te convenga en estos momentos.

Un saludo

fjcg02
17-07-2013, 12:59:32
Te respondo exactamente a lo del WHERE.

Tal y como indica Casi, si en el inner pones el DNI y la categoría, no hace falta que lo pongas en la where.

Un saludo

jafera
17-07-2013, 13:17:27
Gracis de nuevo, ufff aun no he podido realizar las pruebas, estoy en ascuas, jejeje.

El tema de la "normalizacion", no lo he puesto yo así, me viene dado por el fichero txt, en el que el campo COD_CAT es el nexo de union con la descripcion de la categoria en la tabla categorias.

Cuando importo el fichero de texto, COD_CAT es un valor entero que se guarda en el registro de cada corredor y lo que no puedo tener a la vez son dos DNI con dos COD_CAT iguales, entiendo que lo ideal seria una tabla con los corredores una sola vez con varios campos COD_CAT_1, COD_CAT_2 etc. pero de momento no es así ya que la cantidad de repeticiones es bastante baja en relacion a los 60 mil y pico registros.

Resumiendo, voy a hacer lo siguiente:

1- Recibo txt nacional y lo cargo en la tabla temporal
2- Recibo txt autonomico y lo cargo en la tabla temporal
3- Borro toda la tabla definitiva
4- Inserto los datos que quiera de la tabla temporal necional.
5- Hago el left join con los datos de la tabla temporal autonomica.

Es correcto así?

Por cierto todo lo relacionado con el insert lo hago con un componente IBQuery normal en el form, no?

Saludos

Josep

jafera
17-07-2013, 13:28:40
Sí,

a esto se le llaman alias. Cuando cruzas dos tablas, pueden tener campos con el mismo nombre. Para que el motor sepa al campo de qué tabla te refieres, debes especificarle o el nombre de la tabla, o el alias que le hayas puesto.



Correcto lo de los alias ya los uso, yo me referia a si era correcto poner dos comparaciones en el parentesis, para que buscara los registros en que se cumplieran las dos condiciones DNI=DNI y COD_CAT=COD_CAT por el tema comentado de dos veces el mismo DNI con distinto COD_CAT.

Igual no me explique claramente.

Saludos de nuevo

Josep

fjcg02
17-07-2013, 13:34:35
El tema de la "normalizacion", no lo he puesto yo así, me viene dado por el fichero txt, en el que el campo COD_CAT es el nexo de union con la descripcion de la categoria en la tabla categorias.

Bueno, una cosa es cómo te llegue la información y otra es cómo la cargas en tu sistema. Podrías normalizarla en el proceso.


Cuando importo el fichero de texto, COD_CAT es un valor entero que se guarda en el registro de cada corredor y lo que no puedo tener a la vez son dos DNI con dos COD_CAT iguales, entiendo que lo ideal seria una tabla con los corredores una sola vez con varios campos COD_CAT_1, COD_CAT_2 etc. pero de momento no es así ya que la cantidad de repeticiones es bastante baja en relacion a los 60 mil y pico registros.

Eso es un chapucilla. Lo correcto es una tabla de corredores y otra tabla de corredores_categorías con campos idcategoria, DNI, COD_CAT al menos, y que DNI y COD_CAT no puedan tener valores repetidos.



Resumiendo, voy a hacer lo siguiente:

1- Recibo txt nacional y lo cargo en la tabla temporal
2- Recibo txt autonomico y lo cargo en la tabla temporal
3- Borro toda la tabla definitiva
4- Inserto los datos que quiera de la tabla temporal necional.
5- Hago el left join con los datos de la tabla temporal autonomica.

Es correcto así?

Sí.



Por cierto todo lo relacionado con el insert lo hago con un componente IBSQL normal en el form, no?

En principio sí. Es una sentencia normal.


Un saludo

jafera
17-07-2013, 19:12:00
Buenas de nuevo.

He empezado con las pruebas, el insert a la tabla general ha funcionado de maravilla, en un tiempo record tanto desde el IBConsole como desde Delphi, un problema menos.

Luego intento ejecutar el script siguiente en IBConsole y me da error at line 1 - conversion from string""


INSERT INTO CTR0003 ("DORSAL", "NOM", "COGNOM1", "COGNOM2", "CODI_CAT", "LLICENCIA", "DNI", "CLUB", "PUBLICITAT", "CODIUCI")
SELECT C1, C2, C3, C4, C6, C7, C8, C9, C11, C12 FROM CTR0003C
LEFT JOIN CTR0003 ON ( CTR0003C.C8 = CTR0003.DNI AND CTR0003C.C6 = CTR0003.CODI_CAT)
WHERE CTR0003.DNI IS NULL


Creo que he seguido al pie de la letra las instrucciones de escritura del script en cuestión. No se donde puedo haberme equivocado.

Gracias por vuestro tiempo

Josep

fjcg02
17-07-2013, 20:14:20
Desconozco los componentes IB*, pero si con el ibconsole funciona... No se sí habrá algún otro componente de esa familia que te permita hacerlo.
Si no es así puedes hacer una store procedure e invocarla desde el programa.

Saludos

jafera
17-07-2013, 20:20:42
Hola.

El error lo da en IBConsole, no en el componente.


Luego intento ejecutar el script siguiente en IBConsole y me da error at line 1 - conversion from string""


Gracias por todo lo demás ya tengo una parte "cocida" jejeje.

Saludos

fjcg02
17-07-2013, 20:27:32
Ok, no entendí bien. Por lo que te dice, estás intentando cargar un campo de un tipo en otro campo de otro tipo. Tendrás que identificar el campo y hacer un cast para convertirlo al tipo de dato necesario.
En definitiva, que dorsal coincida con el tipo de C1y así sucesivamente.

Saludos

Casimiro Notevi
17-07-2013, 21:13:31
Por cierto, puedes crear la base de datos con el 'character set' que quieras y te ahorras ponerlo en cada campo.
Además creo recordar (ahora mismo no estoy seguro) que también puedes poner el 'collate' en la creación de la bd.
create database xxxxxxxxxxxxx character set yyyyyyy

También te puedes ahorrar poner los nombres entre comillas y entonces dará igual que los escribas en mayúsculas o minúsculas.

CREATE TABLE CTR0003E (
C1 VARCHAR(1),
C2 VARCHAR(1),
C3 VARCHAR(1),
C4 VARCHAR(1),
C5 VARCHAR(25),
C6 VARCHAR(25),
C7 VARCHAR(20),
C8 VARCHAR(3),
C9 VARCHAR(3),
C10 VARCHAR(12),
C11 VARCHAR(12),
C12 VARCHAR(2),
C13 VARCHAR(12),
C14 VARCHAR(30),
C15 VARCHAR(3),
C16 VARCHAR(25),
C17 VARCHAR(15),
C18 VARCHAR(15),
C19 VARCHAR(15)
);
Y si además usas dominios, entonces mucho más cómodo, pero eso lo dejo para otro momento :)

Te lo comento porque me parece "un trabajo de chinos" repetir tantas veces lo mismo y estar pendiente de las comillas, mayúsculas, minúsculas, etc.

fjcg02
17-07-2013, 23:13:33
He comparado las tablas y los campos C1 y C6 tienen diferente tipo que los datos en los que se cargan en la tabla destino. Tendrás que hacer un cast.

Saludos


CTR0003C CTR0003
C1 VARCHAR(3) Diferente DORSAL INTEGER,
C2 VARCHAR(20) NOM VARCHAR(20)
C3 VARCHAR(25) COGNOM1 VARCHAR(25)
C4 VARCHAR(25) COGNOM2 VARCHAR(25)
C6 VARCHAR(3) Diferente CODI_CAT INTEGER,
C7 VARCHAR(14) LLICENCIA VARCHAR(14)
C8 VARCHAR(12) DNI VARCHAR(12)
C9 VARCHAR(25) CLUB VARCHAR(25)
C11 VARCHAR(25) PUBLICITAT VARCHAR(25)
C12 VARCHAR(12) CODIUCI VARCHAR(12)

jafera
18-07-2013, 11:11:52
Buenos dias a todos.

Viendo la respuesta de anoche, he efectuado el cambio en el campo COD_CAT, pasandolo a Integer en la tabla temporal, el otro campo DORSAL, sencillamente lo he quitado del Insert y al hacer la prueba en IBConsole ya no da el error de conversion, pero no tarda 15 segundos, se colapsa y lo aborto


INSERT INTO CTR0003 ("NOM", "COGNOM1", "COGNOM2", "CODI_CAT", "LLICENCIA", "DNI", "CLUB", "PUBLICITAT", "CODIUCI")
SELECT C2, C3, C4, C6, C7, C8, C9, C11, C12 FROM CTR0003C
LEFT JOIN CTR0003 ON (CTR0003C.C8 = CTR0003.DNI)
WHERE CTR0003.DNI IS NULL


Ahora si que me veo superado, yo que pensaba que iba por buen camino y que al final el San Benito saldría del taco de madera y por lo que veo me queda solo la astilla, (chiste antiguo malo, jejeje)

NOTA: En IBConsole lo he dejado en marcha más de 8 minutos y nada, no acaba. En IBExpert más de lo mismo.

Saludos

Josep

fjcg02
18-07-2013, 12:57:34
Una pregunta...
cuanto tarda la select del insert ? Sólo la select

SELECT C2, C3, C4, C6, C7, C8, C9, C11, C12 FROM CTR0003C
LEFT JOIN CTR0003 ON (CTR0003C.C8 = CTR0003.DNI)
WHERE CTR0003.DNI IS NULL

y abusando un poco otra pregunta. Nos puedes poner los indices de las dos tablas ?

Me da que no tendría que tardar casi nada, algo no está suficientemente ajustado.

Un saludo

Casimiro Notevi
18-07-2013, 13:15:38
Debería poner el código fuente de tu programa y datos para hacer pruebas, aunque ya sé que no puedes hacer eso.

jafera
18-07-2013, 13:41:46
La consulta select se hace bastante rapido, pero si lugo toco en el grid donde se muestran los datos en IBConsole, se cuelga.

El código fuente se podria poner, pero no creo que sea lo conveniente ya que aun está bastante verde el tema y el prpopósito del programa es muy especifico y no se si le servirá a mucha gente, talvez para chafardear solo.

Lo que si puedo hacer es conectar con alguien con teamwiever o similar y verlo en directo

El tema índices, pues las tablas temporales no tienen y la definitiva tampoco, no se exactamente donde crearlos

Saludos

Josep

fjcg02
18-07-2013, 13:42:03
Debería poner el código fuente de tu programa y datos para hacer pruebas, aunque ya sé que no puedes hacer eso.

Bueno Casi, en este caso lo que tarda es la sentencia enviada desde la consola. Previamente deberíamos hacerla funcionar a una velocidad aceptable, de ahí que le pida más información. Me da que no tiene que ser inmediata la respuesta, pero de ahí a que tarde más de 8 minutos....

Puedo suponer que no tendría que haber más de un ciento de corredores nuevos. Recuperarlos tendría que ser casi inmediato. Insertar hasta 300 registros... no sé, algo se nos escapa.

A ver qué nos responde jafera.

Un saludo

jafera
18-07-2013, 13:52:13
Creo que lo que tarda es en devolver el select.

Os he dicho que era rápido epro solo los primeros registros, he hecho otra prueba y si navego por el grid, se me va parando a medida que voy bajando el curor.
Si intento bajar la scrollbar de golpe es cuando se cuelga.
No seran unos cientos registros, creo que seran unos miles.

Me da la sensación de que es como si estuviera procesando los registros del select en bloques de unos 30 registros.

Saludos

fjcg02
18-07-2013, 14:10:19
Buenos dias a todos.


INSERT INTO CTR0003 ("NOM", "COGNOM1", "COGNOM2", "CODI_CAT", "LLICENCIA", "DNI", "CLUB", "PUBLICITAT", "CODIUCI")
SELECT C2, C3, C4, C6, C7, C8, C9, C11, C12 FROM CTR0003C
LEFT JOIN CTR0003 ON (CTR0003C.C8 = CTR0003.DNI)
WHERE CTR0003.DNI IS NULL




Varias cosas:
1. Revisa las tablas involucradas en la insert. Hablabas anteriormente de CTR0003, CTR0003E y CTR0003C, y no se´si por error hemos utilizado otras.
2.- ON (CTR0003C.C8 = CTR0003.DNI) Aquí supongo que te falta añadir el campo CODI_CAT, ya que según observabas en otra ocasión este campo interviene.
3.- Crea índices para CTR0003.DNI, CTR0003C.C8, CTR0003.CODI_CAT y CTR0003C.C6 y vuelve a ejecutar la select. Esto tiene que volar !!!!

Si quieres probar rápido, omite el paso 2 y por sólo los índices para CTR0003.DNI y CTR0003C.C8.

Queremos resultados YA !! :D

Un saludo

jafera
18-07-2013, 16:33:48
^\||/^\||/#:-)##:-)##:-)#||-||||-||||-||^\||/^\||/

Ole, ole y ole.

Creo que se ha solucionado, indices, indices e indices.

Yo confundia indices con primary_key.

He puesto los indices en el campo referencia al DNI de las tres tablas et voilà los segundillos que decias.

Ufff que alivio más grande ya ni tiro la toalla ni abandono el barco como las ratas.......

Muchisimas gracias

Josep

fjcg02
18-07-2013, 20:33:56
Eres un crack...;)

Un saludo

fjcg02
19-07-2013, 11:21:58
Como norma general, al menos deberían generarse índices para :

0.- Las primary keys , cuyos ínidices se generan automáticamente.
1.- Aquellos campos por los que se cruza información con otras tablas. Estos son todos los que participan en las JOIN entre tablas. Generalmente coinciden con foreign-keys.
2.- Indice sin repetición en el campo descripción para todas las tablas maestras tipo clave - descripción.
3.- Aquellos campos por los que se ordena habitualmente: nombre, población, ...

Se debe tener en cuenta que añadir demasiados índices ( digo demasiados, no los necesarios ) puede ralentizar las inserciones.

Un saludo

jafera
19-07-2013, 17:52:32
Queriais resultados?

Pues aquí van los resultados cronometrados igual que una carrera, jejeje...

1-Inserción de 63.000 registros procedentes de fichero txt nacional, borrado de los registros que cumplan una condición, consulta para actualizar el campo nacionalidad y el campo fecha de nacimiento, (datos procdentes del codigo UCI) 15 segundos.

2-Inserción de 30.000 registros procedentes de fichero txt autonomico, borrado de los registros que cumplan una condición, consulta para actualizar el campo nacionalidad y el campo fecha nacimiento, (datos procedentes del codigo UCI) 5.5 segundos.

3-Insertar los 30.000 registros que quedan en la tabla temporal nacional a la tabla definitiva 9 segundos.

4-Insertar de los 4.000 registros que quedan en la tabla autonomica y que no esten en la definitiva 3 segundos.

Ni me lo puedo creer, lo he realizado 7 u 8 veces porque me parecia imposible.

Que contento estoy!!!!!!!!

Como ya he dicho en algún que otro hilo anterior, pues eso, que MUCHAS GRACIAS!!!!!! y lo digo así de alto que no chillando.

Saludos calurosos desde la Costa Brava

Josep

Casimiro Notevi
19-07-2013, 17:58:00
^\||/

.

fjcg02
19-07-2013, 21:01:24
Te ha costado pero por fin lo has conseguido. ^\||/

Por aquí también mucho calor y mucha humedad, vamos, todo el día sudando.

Sigue informando.

Ahora planteare hacer la carga directamente desde los ficheros txt !!

Un saludo

fjcg02
19-07-2013, 21:02:42
Ah, y a ver sí gana algún paisano del Euskaltel alguna etapa del Tour