Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 30-11-2009
Avatar de pnikkosis
pnikkosis pnikkosis is offline
Miembro
 
Registrado: nov 2009
Ubicación: Buenos Aires
Posts: 15
Poder: 0
pnikkosis Va por buen camino
Tomar datos de dos bases en insertarlos en una nueva

Buenas gente, voy a intentar explicar lo que quiero hacer con un ejemplo, creo que seria lo mejor. Planteo una situacion hipotetica.
Tengo dos bases de datos que corresponden a dos locales comerciales; digamos que tienen la siguiente forma:

Local1
Codigo Nombre Precio
00001 Pantalon 60
00002 Remera 30
00003 Media 5
00004 Campera 90

Local2
Codigo Nombre Precio
00001 Pantalon 65
00002 Remera 35
00003 Media 5
00005 Zapatilla 85

Las dos bases son iguales (en forma); lo que quiero hacer con delphi es tomar esos datos de la primer tabla y de la segunda y volcarlos a una nueva tabla para despues mostrarlos en un DBGrid. El tema es que la tabla buena va a ser diferente a esa, tendria la forma siguiente:

Codigo Nombre Local1 Local2
00001 Pantalon 60 65
00002 Remera 30 35
00003 Media 5 5
00004 Campera 90 -
00005 Zapatilla - 85

Se entiende? Las columnas de "codigo" y "nombre" siempre son iguales en las dos tablas, la que varia es la de precio.
Lo que tiene es que a veces un codigo esta en una base y no en otra, de ahi lo de juntar los datos de las dos y generar una nueva completa.
Refiriendome a una tabla sola, en delphi tengo dos edit, uno que es para poner el codigo inicial, y otro el final; con eso yo hago un select "desde" y "hasta" tal codigo para que lo muestre (seria select * from tabla1 where codigo >= edit1 and codigo <= edit2 (eso lo tengo funcionando). Me gustaria hascer lo mismo, pero tomando los datos de las dos bases y volcarlos en una nueva.

Mi idea era, hacer un select de cada tabla desde y hasta lo que figure en los edit; que esos datos generen un archivo de texto con cada linea siendo un INSERT y luego un UPDATE; genero dos archivos; despues hago que delphi los corra en la base nueva y asi obtengo una que es la combinacion de las dos.
Me podrian plantear, por que cuando arranca tu aplicacion no haces un select de las dos tablas completas en cada base y los cargas en la base nueva y de ahi trabajas con los edit y el grid?. Si, lo pensé, el tema es que aca simplifique para ejemplificar, yo en realidad estoy laburando con 5 bases y cada tabla tiene aprox. 6000 registros, o sea que si intentara hacer eso la aplicacion tardaria bastante en iniciar, y mas allá de eso, deberia inventar el mismo sistema; un select que me lleve a un script toda la tabla, corra INSERT; un select de la segunda tabla que genere otro script, este que corra un INSERT (para los codigos que no estaban) y un UPDATE para poner los precios en los que si estaban.

Se entendio algo de lo que explique? porque a veces divago y no termino resumiendo nada. Lo que si, no tengo la menor idea de como hacer todo lo que dije, :P me surgio la idea despues de ver como hacian algo parecido.

Desde ya, gracias al que leyo todo esto!

PD: Es firebird 1.5

Última edición por pnikkosis fecha: 30-11-2009 a las 18:39:06.
Responder Con Cita
  #2  
Antiguo 30-11-2009
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.272
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Lo que pretendes más o menos se puede conseguir con una sentencia SQL; No comentas la Base de Datos que utilizas, as´ñi que puede variar la sentencia, pero sería algo así:

Código SQL [-]
Select Tabla1.Nombre, Tabla2.Nombre, Tabla1.Precio as P1, Tabla2.Precio as P2  
from Tabla1 FULL JOIN Tabla2 on Tabla1.Cod=Tabla2.Cod

Esto es en la teoría. Luego hay que saber el caso concreto en que te encuentras. A veces, tal y como tú comentas, una solución que en teoría funciona, puede no ser viable a loa hora de la verdad por muchísimas razones (falta de velocidad, volumen de datos,...)

Tal vez si nos explicaras el caso real y lo que necesitas hacer, te podamos dar una solución más adecuada. O tal vez orientarte por otro camino para llegar a conseguir lo mismo que necesitas.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.

Última edición por Neftali [Germán.Estévez] fecha: 30-11-2009 a las 15:50:30.
Responder Con Cita
  #3  
Antiguo 30-11-2009
Avatar de pnikkosis
pnikkosis pnikkosis is offline
Miembro
 
Registrado: nov 2009
Ubicación: Buenos Aires
Posts: 15
Poder: 0
pnikkosis Va por buen camino
como explique arriba, no es una sola base de datos; asi que eso no se puede hacer; no son dos tablas en una base, son multiples bases con la misma tabla, creo que eso quedo bien explicado.
un select normal no me puede comprender mas de una base ya que con un componente de delphi no se pueden hacer multiples conexiones, de ahi a que tengo que hacer un select de cada tabla, crear un script y correrlo en la base nueva.

te agradezco la ayuda igualmente ^_^
Responder Con Cita
  #4  
Antiguo 30-11-2009
Avatar de rgstuamigo
rgstuamigo rgstuamigo is offline
Miembro
 
Registrado: jul 2008
Ubicación: Santa Cruz de la Sierra-Bolivia
Posts: 1.646
Poder: 17
rgstuamigo Va por buen camino
Arrow

Cita:
Empezado por pnikkosis Ver Mensaje
como explique arriba, no es una sola base de datos; asi que eso no se puede hacer; no son dos tablas en una base, son multiples bases con la misma tabla, creo que eso quedo bien explicado.
un select normal no me puede comprender mas de una base ya que con un componente de delphi no se pueden hacer multiples conexiones, de ahi a que tengo que hacer un select de cada tabla, crear un script y correrlo en la base nueva.

te agradezco la ayuda igualmente ^_^
Aunque hubiese sido bueno que nos comentaras Que servidor de Base de datos usas(MySQL,Oracle,MS sql Server,Firebird,etc,etc.) ¿cual?

Pues, tranquilamente puedes hacer tu consulta SQL aunque sea de multiples base de datos por ejemplo;( siguiendo el ejemplo de Neftali):
Código SQL [-]
Select
MyBaseName1.Tabla1.Nombre,
MyBaseName2.Tabla2.Nombre,
MyBaseName1.Tabla1.Precio as P1,
MyBaseName2.Tabla2.Precio as P2,
from MyBaseName1.Tabla1 FULL JOIN MyBaseName2.Tabla2 on (MyBaseName1.Tabla1.Cod=MyBaseName2.Tabla2.Cod);
o si quieres mas cortita(usando alias)
Código SQL [-]
Select T1.Nombre,T2.Nombre,T1.Precio as P1, T2.Precio as P2
from MyBaseName1.Tabla1 T1 FULL JOIN MyBaseName2.Tabla2 T2 on (T1.Cod=T2.Cod);
.
Desde luego debes tener los privilegios adecuados para ambas base de datos y sus respectivas tablas.
Nota: Probado con MySQL y los componentes Zeos (aunque no exactamente la misma consulta)
Saludos...
__________________
"Pedid, y se os dará; buscad, y hallaréis; llamad, y se os abrirá." Mt.7:7
Responder Con Cita
  #5  
Antiguo 30-11-2009
Avatar de pnikkosis
pnikkosis pnikkosis is offline
Miembro
 
Registrado: nov 2009
Ubicación: Buenos Aires
Posts: 15
Poder: 0
pnikkosis Va por buen camino
Hay algo que yo no entiendo todavia, o evidentemente no lo aprendi.

Segun lo que estuve haciendo, para conectarme a una base firebird (lo puse al final de todo que la estoy usando) lo que hago es poner en delphi 3 componentes, un IBdatabase con los datos de la base, un IBquery linkeado a esa base y un DataSource linkeado al ibquery. Cuando quiero hacer una consulta, hago IBQuery1.SQL := 'select blablablablablabla'; para ver los resultados pongo un DBGrid linkeado al datasource.
Yo en ese query no puedo hacer referencia a dos bases diferentes, porque ese query esta linkeado a una sola base; al igual que el DBgrid no puedo linkearlo a mas de un datasource.
Responder Con Cita
  #6  
Antiguo 30-11-2009
Avatar de rgstuamigo
rgstuamigo rgstuamigo is offline
Miembro
 
Registrado: jul 2008
Ubicación: Santa Cruz de la Sierra-Bolivia
Posts: 1.646
Poder: 17
rgstuamigo Va por buen camino
Arrow

Cita:
Empezado por pnikkosis Ver Mensaje
Hay algo que yo no entiendo todavia, o evidentemente no lo aprendi.

Segun lo que estuve haciendo, para conectarme a una base firebird (lo puse al final de todo que la estoy usando) lo que hago es poner en delphi 3 componentes, un IBdatabase con los datos de la base, un IBquery linkeado a esa base y un DataSource linkeado al ibquery. Cuando quiero hacer una consulta, hago IBQuery1.SQL := 'select blablablablablabla'; para ver los resultados pongo un DBGrid linkeado al datasource.
Yo en ese query no puedo hacer referencia a dos bases diferentes, porque ese query esta linkeado a una sola base; al igual que el DBgrid no puedo linkearlo a mas de un datasource.
Entiendo lo que mencionas, pero lo que estoy proponiendo es hacer la referencias a las dos bases de datos en la consulta SQL, tal cual como te he puesto en el ejemplo.Tan solo reemplaza MyBaseName1,MyBaseName2,Table1,Table2,por los nombres de tus Bases de Datos y Tablas respectivamente.Al menos probalo...y luego nos comentas..
__________________
"Pedid, y se os dará; buscad, y hallaréis; llamad, y se os abrirá." Mt.7:7
Responder Con Cita
  #7  
Antiguo 01-12-2009
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Si es Firebird lamentablemente ese tipo de consulta no funcionará, a menos que las tablas pertenezcan a una misma base de datos.

En Firebird, hasta el momento, no se pueden realizar consultar entre dos o más bases de datos. Se espera que para la versión 2.5 o 3 se añada dicha característica.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #8  
Antiguo 01-12-2009
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.272
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por pnikkosis Ver Mensaje
un select normal no me puede comprender mas de una base ya que con un componente de delphi no se pueden hacer multiples conexiones
Sí se puede en algunos servidores y con algunos componentes, de ahí mi pregunta.
Sin ir más lejos en SQL Server puedes utilizar LINKED SERVERS para lanzar una consulta como la que necesitas (que involucre varias tablas de varios servidores).
Desconozco si en otros SGBD's hay algo similar.

AÑADO: Veo que rgstuamigo ya ha contestado.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #9  
Antiguo 01-12-2009
Avatar de pnikkosis
pnikkosis pnikkosis is offline
Miembro
 
Registrado: nov 2009
Ubicación: Buenos Aires
Posts: 15
Poder: 0
pnikkosis Va por buen camino
Cita:
Empezado por Delphius Ver Mensaje
Si es Firebird lamentablemente ese tipo de consulta no funcionará, a menos que las tablas pertenezcan a una misma base de datos.

En Firebird, hasta el momento, no se pueden realizar consultar entre dos o más bases de datos. Se espera que para la versión 2.5 o 3 se añada dicha característica.

Saludos,
Es lo que yo estaba diciendo. De ahi a que quiero hacer la consulta y generar un script con lo que me devuelva, para poder asi cargarlo en la base que va a incluir los datos de todas las demas.
Responder Con Cita
  #10  
Antiguo 02-12-2009
Avatar de Axel_Tech
Axel_Tech Axel_Tech is offline
Miembro
 
Registrado: nov 2008
Ubicación: lugar en que está ubicado algo.
Posts: 85
Poder: 16
Axel_Tech Va por buen camino
Yo me encontré con un problema parecido, pero tenía 2 grandes diferencias con el tuyo:
1.- Sólo tenía que pasar una tabla (parte) de una base de datos Firebird a otra en vez de dos como es tu caso.
2.- Con lo de parte me refiero a que no tenía que pasar la tabla entera, seleccionaba los registros que me interasaban, ya fuera el criterio con un rango entre 2 fechas o por descripción. La selección mayor que tenía que "exportar" como mucho tendría unos 1500 registros, no 6000 como es tu caso. No se como te irá esta solución en cuanto a velocidad y/o rendimiento.
Aunque pensándolo bien después de leer esto:
Cita:
Refiriendome a una tabla sola, en delphi tengo dos edit, uno que es para poner el codigo inicial, y otro el final; con eso yo hago un select "desde" y "hasta" tal codigo para que lo muestre (seria select * from tabla1 where codigo >= edit1 and codigo <= edit2 (eso lo tengo funcionando)
creo que es algo parecido a lo que hago yo.
De todas formas te cuento:

Primero habría que hacer un select de la tabla de la base de datos Local1 (si es con el criterio "desde" y "hasta" mencionado antes mejor) con su IBQuery correspondiente (vamos a llamarle IBQuery1).
Después la recorremos, y hacemos un select de la tabla de Local2 (IBQuery2) utilizando como criterio por ejemplo el código del registro por el que vamos de IBQuery1.
Una vez echo esto montaríamos una cadena con el INSERT, que tendría como campos el Código, Nombre y Precio de IBQuery1 + el precio de IBQUERY2.
Ejecutaríamos el INSERT y ya tendríamos un registro en la nueva tabla (puedes usar un IBQuery3 o borrar el SQL de IBQuery2 e insertarlo desde ahí mismo). Mas o menos el código sería algo así:
Código Delphi [-]
IBQuery1.Active := False;
IBQuery1.SQL.Clear;
IBQuery1.SQL.Text := 'SELECT CODIGO, NOMBRE, PRECIO FROM TABLA1 WHERE CODIGO >= EDIT1 AND CODIGO <= EDIT2'; 
IBQuery1.Active := True;        //select de la tabla Local1
IBQuery1.First;            //nos posicionamos en el primer registro

while not IBQuery1.Eof do    //la recorremos con un while
    begin
        IBQuery2.Active := False;
        IBQuery2.SQL.Clear;
        IBQuery2.SQL.Text := 'SELECT CODIGO, NOMBRE, PRECIO FROM TABLA2 ';
        IBQuery2.SQL.Add('WHERE CODIGO = ' + IBQuery1.FieldByName('CODIGO').AsString);
        IBQuery2.Active := True;    //select de la tabla Local2

        cadena := 'INSERT INTO TABLA3(CODIGO, NOMBRE, PRECIO_LOCAL1, PRECIO_LOCAL2) VALUES (';
        cadena := cadena + IBQuery1.FieldByName('CODIGO').AsString + ',';
        cadena := cadena + QuotedStr(IBQuery1.FieldByName('NOMBRE').AsString) + ',';
        cadena := cadena + IBQuery1.FieldByName('PRECIO').AsString + ',';   //precio1
        cadena := cadena + IBQuery2.FieldByName('PRECIO').AsString;   //precio2
        cadena := cadena + ')';    //cadena del insert montada
        
        IBQuery2.SQL.Clear;
        IBQuery2.SQL.Text := cadena;   
        IBQuery2.ExecSQL;    //metemos el nuevo registro
        IBQuery1.Next;    //pasamos al siguiente registro de la tabla de Local1
    end;

Obviamente cambiando los nombre de las tablas, campos, controles, etc. por los tuyos. Espero que te sirva
* Nota: cada IBQuery apunta a su IBDatabase correspondiente.
__________________
No hope, no dreams, no love, my only escape is Underground

Última edición por Axel_Tech fecha: 02-12-2009 a las 11:34:10.
Responder Con Cita
  #11  
Antiguo 02-12-2009
Avatar de pnikkosis
pnikkosis pnikkosis is offline
Miembro
 
Registrado: nov 2009
Ubicación: Buenos Aires
Posts: 15
Poder: 0
pnikkosis Va por buen camino
Axel, sos un tipo groso, entendiste perfecto como era la cosa!

Lo acabo de leer y no estoy en la compu donde tengo el delphi, asi que cuando llegue me pongo a probarlo; te hago una consulta, esto va a hacer un select de la tabla en la base1 desde tal codigo hasta tal codigo; despues va a hacer un select de la segunda tabla en la segunda base donde el codigo sea el mismo que los seleccionados de la base1. Despues va a hacer un insert linea por linea en la tercer base hasta que se termine el select1.
Mi consulta era, a veces pasa que en la base2 hay un codigo que no esta en la base1, como en el ejemplo que yo puse en el primer post. Por eso mi idea inicial era tomar el select de la primer base y hacer insert; tomar el select de la segunda base y hacer insert y despues update; y el select de la segunda tambien contemplarlo por lo que haya en los edit en vez de lo que me dio como resultado el select1, entonces si hay un codigo que existe en una pero en la otra no quedaria agregado igual.
Igualmente si, la base1 es la que tiene la "mayoria" de los codigos, y entre las bases, si el codigo existe su nombre es igual, o sea que el campo codigo y nombre si los iba a tomar como referencia para crear la tabla nueva. Mi idea, es hacer esto a las N bases, o sea que en el ejemplo son dos, pero ponele que fueran 5 o 20 bases.

Volvi a releer tu propuesta, y se me ocurrio lo siguiente (no lo escribo en codigo porque a algo le voy a errar, pero decime si mi teoria seria correcta)
Tengo los componentes IBQuery1, 2, 3....N correspondiente a cada base para hacer los select, y un IBQueryX que va a ser el que grabe la info en la tabla que tenga los datos de todas.
Empiezo con un select en el query1 desde y hasta lo que me indiquen los edit. Me posiciono en la primer linea; abro un while query1 eof y en una variable string voy agregando como vos hiciste los campos, nada mas que el precio2 lo dejo vacio, uso el queryX para grabar a la tabla nueva.
Cuendo termina el while hago un select del query2, igual que el 1, contemplando los edit desde y hasta, abro un while query2 eof y en la variable agrego todo el insert (que si ya se habia insertado con el del query1 lo va a saltear, y sino lo va a agregar) y despues un update (para agregarle el precio2). Termina el while, y asi sucesivamente hasta la cantidad de bases que tenga, un select de la tercera, abro while, insert y update, cierro while; un select de la cuarta, abro while etc etc etc.

En teoria funcionara?

Te cuento cuando llego a la compu donde tengo delphi. Igualmente, me dieste una idea de como arrancar! mil gracias!

Que lindo seria esto si laburara con firebird 2.1, donde podes hacer un "UPDATE OR INSERT" que contempla justo estos casos.

Última edición por pnikkosis fecha: 02-12-2009 a las 13:56:53.
Responder Con Cita
  #12  
Antiguo 03-12-2009
Avatar de Axel_Tech
Axel_Tech Axel_Tech is offline
Miembro
 
Registrado: nov 2008
Ubicación: lugar en que está ubicado algo.
Posts: 85
Poder: 16
Axel_Tech Va por buen camino
Con más de 2 bases de datos se complica la cosa. Yo creo que sí funcionaría, aunque veo un par de inconvenientes:
1.- Con tanto INSERT y UPDATE no se que rendimiento obtendrías. Sería cuestión de probarlo.
2.- Cuando llegas a este punto:
Cita:
(que si ya se habia insertado con el del query1 lo va a saltear, y sino lo va a agregar)
desconozco si se puede evitar que se muestre una excepción por violación de clave primaria cuando intentas insertar un producto que ya existe. Nunca se me ha dado el caso, quizás si se pueda pero ignoro cómo.

Tengo en mente otra solución: utilizando tablas temporales (una por cada tabla de cada base de datos) y un procedimiento almacenado con 2 cursores. Las tablas temporales las rellenarías tal y como hemos visto hasta ahora, recorriendo las IBQuery y utilizando el criterio "desde" y "hasta".
Una vez rellenas (para evitar errores te recomiendo que las tablas se llamen igual o parecido en la base de datos final, y los campos también) el SP sería algo tal que así:
Código SQL [-]
/*este primer cursor es para insertar directamente los que no existen en la tabla1, 
y nos quitamos ese problema de un plumazo. 
En este caso es con la tabla2, sería de la misma forma hasta tablaN:*/
FOR 
    SELECT A.CODIGO, A.NOMBRE, A.PRECIO FROM TABLA2 A 
    WHERE NOT EXISTS (SELECT B.CODIGO FROM TABLA1 WHERE B.CODIGO=A.CODIGO)
    INTO :COD, :NOM, :PREC2    /*variables que habrás tenido que declarar previamente*/
DO
    INSERT INTO TABLA_FINAL (CODIGO, NOMBRE, PRECIO2) VALUES (:COD, :NOM, :PREC2);

FOR  /*con la ayuda de este otro cursor para recorrerla, hacemos la consulta de la tabla1*/
     SELECT CODIGO, NOMBRE, PRECIO FROM TABLA1
     INTO :COD, :NOM, :PREC         /*:PREC es otra variable que tienes que declarar*/
DO
     BEGIN
        SELECT PRECIO FROM TABLA2 WHERE CODIGO=:COD
        INTO :PREC2    
        INSERT INTO TABLA_FINAL (CODIGO, NOMBRE, PRECIO1, PRECIO2) VALUES (:COD, :NOM, :PREC, :PREC2);

        SELECT PRECIO FROM TABLA3 WHERE CODIGO=:COD
        INTO :PREC2    
        INSERT INTO TABLA_FINAL (CODIGO, NOMBRE, PRECIO1, PRECIO2) VALUES (:COD, :NOM, :PREC, :PREC2);

        /*y así sucesivamente, hasta que llegues a tablaN*/
     END

Un SP es más potente y más rapido que tanto INSERT y UPDATE. Tendrías que depurarlo un poco y adaptarlo a tus necesidades. Como ya he dicho antes todo es cuestión de probarlo.
__________________
No hope, no dreams, no love, my only escape is Underground
Responder Con Cita
  #13  
Antiguo 03-12-2009
Avatar de pnikkosis
pnikkosis pnikkosis is offline
Miembro
 
Registrado: nov 2009
Ubicación: Buenos Aires
Posts: 15
Poder: 0
pnikkosis Va por buen camino
Leyendo articulos de como hacer insert+update dependiendo de si existe o no un primary key en la tabla, llegue a lo siguiente:
(de nuevo, estoy con firebird 1.5, que boludes seria si tuviera 2.1)

Un SP con algo como esto:

Código:
if exists('CODIGO') then 
update TABLANUEVA set
LOCAL2 = (el PRECIO que me dio el select del query2) 
where CODIGO = (codigo del select del query2);
else insert into TABLANUEVA (blablablabla el insert normal)
tendria que crear un stored procedure dentro de mi base nueva, y llamar a ese SP en cada while que haga.
entonces en el primer while (del query1 de la base1) hago un insert unicamente porque en la base nueva no hay ningun dato. Y a partir de la segunda base hasta la baseN dentro de los while corro un SP como este, si el codigo ya existe va a actualizar el campo que le correspone a esa tabla (el precio) y sino existe va a insertar la linea entera.

Mi problema radica en que no tengo la menor idea como hacer un SP jaja, estuve leyendo pero no entiendo muy bien eso de especificar input y outputs, y tambien me doy cuenta que en el stored procedure yo tendria que hacer referencia a campos de selects que estan en delphi, y eso tampoco tengo idea; por ejemplo, si empezara el if exists ('CODIGO'), que hace referencia al campo codigo del select del query2, pondria en delphi algo como
if exists ('+IBQuery2.FieldByName('CODIGO').AsString+'), pero como le digo a firebird que ese campo codigo esta en un select que hice con un query en delphi?
Sino lo que se me ocurrio hacer en delphy es directamente tirar un CREATE PROCEDURE con todos esos datos adentro y despues ejecutar el ibquery, pero me parece medio al pedo eso, tendria que hacer un create SP y un drop SP por cada linea del select, le saca el proposito al stored procedure.
Asi que ahora ando peleando con eso.
-----------

Soy un nabo no? hay un componente que es IBStoredProcedure, decime que lo linkeo a la base y despues en StoredProcName elijo el que tengo en la base y me deja linkear variables de delphi con variables de firebird

Última edición por pnikkosis fecha: 03-12-2009 a las 23:32:41.
Responder Con Cita
  #14  
Antiguo 04-12-2009
Avatar de pnikkosis
pnikkosis pnikkosis is offline
Miembro
 
Registrado: nov 2009
Ubicación: Buenos Aires
Posts: 15
Poder: 0
pnikkosis Va por buen camino
Ok, lo tengo casi listo, tengo un problema con el SP nada mas, te cuento lo que hice:

Código SQL [-]
CREATE PROCEDURE SP_UPDATEORINSERT2(
codigo VARCHAR(20),
nombre VARCHAR(50),
precio NUMERIC(10,4),
AS BEGIN
IF (:codigo = 'T.CODIGO')
THEN UPDATE TABLANUEVA T SET
LOCAL2 = recio WHERE CODIGO = :codigo;
ELSE INSERT INTO TABLANUEVA (CODIGO,NOMBRE,LOCAL1,LOCAL2)
VALUES (:codigo,:nombre,0,recio)
END;

Ya aprendi a asignarle valores a las variables desde delphi,haciendo IBStoredProc1.Params[0...N].AsString o ParamsByName y el nombre, y despues que tengo todos asigandos hago .ExecProc me funciona el correrlo
Ahora, tengo dos problemas con ese SP: 1, no me esta tomando cuando el codigo existe, ponele que tengo el codigo 001 en la tabla y pongo como la variable :codigo 001, no corre el update sino que hace un insert y me quedan dos filas en la tabla con el codigo 001, raro.
Y el otro problema que tengo es... no se si como actualiza o que, pero hice una interfaz chica de prueba en delphi, con 3 edits le asigno valores a las variables y un boton corre el SP, pero hasta que no cierro la aplicacion la tabla parece que no se actualiza; uso el IBExpert como Database manager y desconecto la base, la vuelvo a abrir y lo que corri en el SP no aparece, pero si cierro la aplicacion de delphi, ahi se graba a la base y me aparece. Tiene algo que ver con hacer un commit? Tengo que tocar el componente IBTransaction?
Responder Con Cita
  #15  
Antiguo 04-12-2009
Avatar de Axel_Tech
Axel_Tech Axel_Tech is offline
Miembro
 
Registrado: nov 2008
Ubicación: lugar en que está ubicado algo.
Posts: 85
Poder: 16
Axel_Tech Va por buen camino
A ver, vamos por partes.
Cita:
Empezado por pnikkosis Ver Mensaje
Ya aprendi a asignarle valores a las variables desde delphi,haciendo IBStoredProc1.Params[0...N].AsString o ParamsByName y el nombre
Cierto, la forma de pasarle datos a un SP desde Delphi (o desde otro lenguaje) es por parámetros de entrada, o "inputs" como tú los has llamado antes

Cita:
Empezado por pnikkosis Ver Mensaje
Ahora, tengo dos problemas con ese SP: 1, no me esta tomando cuando el codigo existe, ponele que tengo el codigo 001 en la tabla y pongo como la variable :codigo 001, no corre el update sino que hace un insert y me quedan dos filas en la tabla con el codigo 001, raro
Seguramente tenga que ver con que no has definido clave o claves primarias en la nueva tabla. Define como tal por ejemplo el campo código.

Cita:
Empezado por pnikkosis Ver Mensaje
Y el otro problema que tengo es... no se si como actualiza o que, pero hice una interfaz chica de prueba en delphi, con 3 edits le asigno valores a las variables y un boton corre el SP, pero hasta que no cierro la aplicacion la tabla parece que no se actualiza; uso el IBExpert como Database manager y desconecto la base, la vuelvo a abrir y lo que corri en el SP no aparece, pero si cierro la aplicacion de delphi, ahi se graba a la base y me aparece. Tiene algo que ver con hacer un commit? Tengo que tocar el componente IBTransaction?
Sí, es problema de transacciones. Por lo que me cuentas hasta que no cierras el programa no hace el commit. Ya que has nombrado el IBTransaction puedes hacer que el IBStorecProc apunte a una IBTransaction y esta a su vez apunte a tu IBDatabase. Debes poner las propiedades del IBTransaction DefaultAction := TACommit y AutoStopAction := saCommit.

De todas formas sigo manteniendo en pie mi planteamiento anterior ya que ejecutarías el SP una sola vez, y tú lo vas a ejecutar por cada registro que exista. Si hay 6000 pues 6000 veces pero me reitero otra vez, todo es cuestión de probarlo y ver el rendimiento que obtienes.
__________________
No hope, no dreams, no love, my only escape is Underground
Responder Con Cita
  #16  
Antiguo 04-12-2009
Avatar de pnikkosis
pnikkosis pnikkosis is offline
Miembro
 
Registrado: nov 2009
Ubicación: Buenos Aires
Posts: 15
Poder: 0
pnikkosis Va por buen camino
Ahora entendí lo de los primary keys y foreing keys... me largue a usar firebird sin entender un joraca! jaja; en fin, agregue "codigo" como PK, y volvi a correr el SP asignandole valores, ahora si no existe lo inserta (igual que antes), pero cuando vuelvo a ponerle el mismo codigo e intentar correrlo me tira que no puede haber dos filas con el mismo codigo, asi que el IF no me esta resolviendo bien el THEN, deberia hacer un UPDATE pero lo saltea, estara mal la condicion de (:codigo = 'T.CODIGO')?
Porque T.CODIGO entre comillas simples no esta haciendo que eso sea como un string en vez de reconocerlo como referencia al campo de una tabla?, igualmente probé sacandole las comillas simples y cuando quiero compilar el SP me dice justo que hay un error en esa linea, column unknown... pero la columna codigo esta en esa tabla. Cuando adentro del update hago referencia a la columna PRECIO no me tira el mismo error.
-------------
el problema esta en la igualdad me parece... yo no le puedo decir a una igualdad que una variable con X valor sea igual a una columna entera, no le estoy espeficando a que CODIGO tiene que ser igual; deberia hacer un IF EXISTS pero no me reconoce el EXISTS

Última edición por pnikkosis fecha: 04-12-2009 a las 15:51:41.
Responder Con Cita
  #17  
Antiguo 04-12-2009
Avatar de Axel_Tech
Axel_Tech Axel_Tech is offline
Miembro
 
Registrado: nov 2008
Ubicación: lugar en que está ubicado algo.
Posts: 85
Poder: 16
Axel_Tech Va por buen camino
Cierto, no me había fijado antes, 'T.CODIGO' lo está interpretando como una cadena de caracteres.
No estoy seguro de que lo que pretendes con ese if se pueda hacer de esa manera, pues como bien has dicho en la última frase no puedes comparar una variable (en este caso un parámetro de entrada) con una columna entera de una tabla.
Puedes hacerlo con un EXISTS como te dije en el SP que puse más arriba:
Código SQL [-]
CREATE PROCEDURE SP_UPDATEORINSERT2(
codigo VARCHAR(20),
nombre VARCHAR(50),
precio NUMERIC(10,4),
AS 
DECLARE VARIABLE COD VARCHAR(20);   /*declaras una variable para meter el codigo de la consulta siguiente:*/
BEGIN

SELECT A.CODIGO 
FROM TABLA2 A 
WHERE NOT EXISTS (SELECT B.CODIGO FROM TABLANUEVA B WHERE B.CODIGO=A.CODIGO)
INTO :COD
Esta consulta mira si ya existe el codigo en la tabla, y entonces haces un if:
Código SQL [-]
IF :COD IS NULL THEN
      INSERT INTO TABLANUEVA.....
ELSE
      UPDATE TABLANUEVA.....

si :COD es null haces el INSERT, si no haces el UPDATE. A ver así que tal.
__________________
No hope, no dreams, no love, my only escape is Underground
Responder Con Cita
  #18  
Antiguo 05-12-2009
Avatar de pnikkosis
pnikkosis pnikkosis is offline
Miembro
 
Registrado: nov 2009
Ubicación: Buenos Aires
Posts: 15
Poder: 0
pnikkosis Va por buen camino
Resolvi el problema del IF; declare una variable :exists como output y antes del if hice:

Código SQL [-]
select count(*) from TABLANUEVA where CODIGO = :codigo INTO :exists;

(entonces si hay algun registro de codigo con el valor asignado a :codigo, el count me va a devolver un valor mas grande que cero)

y entonces el if lo empiezo asi: IF (:exists > 0) then uptade blabalbla else insert into.

Y funcionó. Y lo de que no comiteaba a la base tenias razon, era el IBTransactrion, lo tenia en saNone, lo cambie y despues del procedure commitea perfecto.

Asi que los dos problemas restantes estan solucionados, creo que ahora puedo ponerme a desarrollar! Te agradezco Axel por tu ayuda que fue invaluable y a los demas tambien. Aunque presiento que vas a ver muchas mas preguntas mias por el foro dando vueltas, soy asi de pesado para todo! jaja.
Responder Con Cita
  #19  
Antiguo 09-12-2009
Avatar de Axel_Tech
Axel_Tech Axel_Tech is offline
Miembro
 
Registrado: nov 2008
Ubicación: lugar en que está ubicado algo.
Posts: 85
Poder: 16
Axel_Tech Va por buen camino
Me alegro que por fin tengas todo claro
__________________
No hope, no dreams, no love, my only escape is Underground
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Tomar datos del lector de código de barras jam888 OOP 4 22-03-2010 17:53:03
Tomar datos de otra aplicacion dblx API de Windows 4 23-12-2008 01:16:38
Tomar datos de excel vinagre3ro Internet 2 04-10-2006 09:59:28
Hola soy muy nueva en esto de las bases de datos y deseo imprimir tablas nuri Impresión 1 05-07-2005 19:49:31
Como mostrar los datos para luego insertarlos? judoboy OOP 8 14-05-2003 09:51:51


La franja horaria es GMT +2. Ahora son las 03:28:34.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi