Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   referencia multiples bases de datos en una Consulta (Query) en firebird (https://www.clubdelphi.com/foros/showthread.php?t=70364)

novato_erick 17-10-2010 01:50:02

referencia multiples bases de datos en una Consulta (Query) en firebird
 
Hola a todos:

La pregunta es la siguiente:

Tengo 4 bases de datos:
Inventario
Ventas
Seguridad
Planilla

Deseo realizar un scrip sql para extraer la informacion de por lo menos dos Baces de datos (Firebird). en una misma conexion.

En Mysql lo he hecho de esta manera:

select e.nombre, e.apellido from PLANILLA. empleado e INNER JOIN
seguridad.usuario u ON (e.cedula=e.cedula)
WHERE e.activo='S'

En firebird como lo haria?

Saludos a todos;

Casimiro Notevi 17-10-2010 02:02:08

¿4 bases de datos?, supongo que quieres decir 4 tablas de una base de datos.

La sql es más o menos igual:

Código SQL [-]
select cli.nombre, cli.telefono, cat.clase
from tbclientes cli
inner join tbcategorias cat on cat.codigo=cli.codigo
where ...

novato_erick 17-10-2010 02:13:17

No... son cuatro base de datos cada una de ella tiene sus tablas.

en pocas palabras es una consulta externa de una base de datos ejemplo:

la idea es unificar tablas de dos bases de datos diferentes extrayendo informacion de cada una de ella en una sola conexion con FIREBIRD.


lo digo porque en mysql se puede hacer y en firebird lei que la version 2.5 es capaz de realizarlo aqui muestro una frase "Otras mejoras en SQL incluyen la introducción de transacciones autónomas y la capacidad para consultar otras bases de datos mediante EXECUTE STATEMENT.".

como lo hago?


Saludos;

Casimiro Notevi 17-10-2010 12:36:48

Pues echa un vistazo para ver cómo funciona esa nueva instrucción. No la he usado porque no trabajo con firebird 2.5 todavía.

Actualmente lo haría mediante creando una conexión por cada base de datos, recogiendo los datos necesarios de cada una de las bases de datos y trabajando luego con esos datos.

De todas formas, no sé por qué tienes 4 bases de datos para eso, me parece muy extraño.

novato_erick 17-10-2010 21:55:10

Lo estoy realizando ya que estructuro mejor la base de datos y mis sistemas de Punto de venta, Planilla, manteniendo los datos en cada DB por ejemplo al crear un sistema de planilla puedo ingresar los empleados pero al vender el sistema de punto de venta e inventario estos empleados no todos usaran el sistema de ventas e inventarios esto me evita duplicar los datos en mi estructura de base de datos y mantener mejor la integridad.

Otro ejemplo seria y muy facil que unos de mis propios empleado es mi cliente para que necesitaria volver a copiar todos los datos de mi empleado y ponerlo como cliente si ya lo tengo.

Creo que se ve complejo pero es una teoria que me ah funcionado...

Lo uso asi porque no te imagina lo pequeño que se hace la base de datos en espacio y lo unico que necesito es desempeño de mi servidor porque le dejo la mayoria del trabajo a el.

Ah... aclaro no soy experto en sql o base de datos pero asi fue como me enseñaron y le aye logica al manual de arquitectura de base de datos e integridad de datos.

otra cosa que me llevo a esto es que donde empeze a trabajar habia dos base de datos entre ambas tenia aproximadamente 600mb con tan solo 4500 registro sin contar los registro duplicados y las tablas sin registro alguno.

al volver a estructurarlo tan solo los mismo 4500 registro sin duplicidad de datos y sin tablas vacias se me redujo a 6mb pero claro en 4 DB.

Es por eso que lo realizo de esa manera.

sitrico 21-10-2010 21:19:37

Pues según lo que comentas con la versión 2.5 si se puede hacer, mira este documento, Busca "EXECUTE STATEMENT" en la Pagina 67,

http://www.firebirdsql.org/rlsnotes/...leaseNotes.pdf

Creo que hay esta tu respuesta.

PD nunca lo he usado, pero en un proyecto que analizo actualmente me caerá muy bien esta nueva capacidad, solo que yo la tendré que usar con DB diferentes en servidores diferentes :cool:

Casimiro Notevi 21-10-2010 21:42:47

Cita:

Empezado por novato_erick (Mensaje 379545)
[..] Es por eso que lo realizo de esa manera.

Bueno, si te va bien así, pues estupendo.
Pero no es lo ideal, tampoco voy a explicar razones porque estoy seguro de que no lo vas a cambiar :)

novato_erick 10-01-2013 17:48:27

Hola Casimiro

hace mas de un mes había hecho una consulta esta consulta el cual lo había dejado para avanzar en otras solicitudes... sin embargo estoy retomando el tema pero me dejaste con esta intriga.
Cita:

Bueno, si te va bien así, pues estupendo.
Pero no es lo ideal, tampoco voy a explicar razones porque estoy seguro de que no lo vas a cambiar
el asunto es que tengo dos bases de datos una el cual contiene los datos de inventario y la otra base contiene las ventas
cual seria tu sugerencia amigo para poder traer datos que consultar en base de datos de inventario y base de datos de ventas...

Agradeciendo mucho su ayuda...

Saludos

novato_erick

Casimiro Notevi 10-01-2013 17:57:38

Hola novato_erick, tal y como se ha comentado antes, puedes traerte los datos que necesitas de distintas bases de datos usando "execute statement", aunque lo que quería darte a entender es que yo lo haría de otra forma, es que no se entiende el motivo de tener 4 bases de datos distintas.
Lo normal es tener una base de datos con las tablas necesarias.

Desconozco si tu caso es algo "especial", deberías explicarlo ampliamente para que nos hagamos una idea clara del mismo y aconsejarte una cosa u otra.

Saludos :)

novato_erick 10-01-2013 18:10:47

El Administrador de proyectos anterior había sugerido utilizar una base de datos para cada sistema ejemplo:

Inventario, Ventas, Planilla, Contabilidad desconozco porque la sugerencia para mi es igual a lo que sugeriste...
Cita:

Casimiro dice: Lo normal es tener una base de datos con las tablas necesarias.
Sin embargo en Inventario solamente hay información de producto y Ventas los detalles de ventas, etc. pero ahora me solicitaron realizar una consulta el cual tengo que consultar los productos vendidos pero la referencia de consulta no es el codigo de barra para traer la información encontrada en la base de datos ventas si no un campo llamado CODIGO3 que aparentemente lo usaron como código alternativo.

ahora la consulta debe ser a partir de ese CODIGO3 pero ese código no esta en la tabla DETALLE_FACTURA...



Espero haberme explicado...

Saludos...

novato_erick 10-01-2013 18:28:38

Estos son los campos de la tabla de inventario y Detalle_facturas

Código SQL [-]
CREATE TABLE INVENTARIO (
  FECHA_ALTA DATE NOT NULL,
  COD_BARRAS VARCHAR(30) CHARACTER SET NONE NOT NULL COLLATE NONE,
  CODIGO2 VARCHAR(30) CHARACTER SET NONE COLLATE NONE,
  CODIGO3 VARCHAR(30) CHARACTER SET NONE COLLATE NONE,
  COD_FAMILIA VARCHAR(15) CHARACTER SET NONE COLLATE NONE,
  COD_UBICACION INTEGER,
  COD_UNIDAD INTEGER,
  NOMBRE VARCHAR(200) CHARACTER SET NONE NOT NULL COLLATE NONE,
  NOMBRE2 VARCHAR(100) CHARACTER SET NONE COLLATE NONE,
  PRECIO_COMPRA FLOAT DEFAULT 0 NOT NULL,
  FECHA_ULTIMACOMPRA DATE,
  STOCK_MINIMO CANTIDAD_FLOAT NOT NULL,
  PORC_IV NUMERIC(15, 3) DEFAULT 13 NOT NULL,
  GRAVADO LOGICO NOT NULL,
  IMPUESTO_INCLUIDO LOGICO NOT NULL,
  IMAGEN BLOB,
  PREVEN_1 FLOAT DEFAULT 0 NOT NULL,
  BASECALCULO_1 INTEGER,
  COEFA_1 NUMERIC(6, 2),
  SUMAFIJA_1 FLOAT DEFAULT 0 NOT NULL,
  REDONDEO_1 INTEGER,
  PRECIOSINIV_1 FLOAT DEFAULT 0 NOT NULL,
  PRECIOCONIV_1 FLOAT DEFAULT 0 NOT NULL,
  STOCK CANTIDAD_FLOAT NOT NULL,
  PRECIO_DEFECTO INTEGER DEFAULT 1,
  FK_PROVEEDOR INTEGER,
  CONSIGNACION CHAR(1) CHARACTER SET NONE DEFAULT 'N' NOT NULL COLLATE NONE,
  PESONETO NUMERIC(18, 3),
  PRESENTACION NUMERIC(10, 3),
  VENTAALPESO LOGICO);

Esta es la Tabla DETALLE_FACTURAS
Código SQL [-]
CREATE TABLE DETALLE_FACTURAS (
  ID_DETALLE_FACTURA INTEGER NOT NULL,
  FECHA DATE DEFAULT 'NOW',
  CODIGO_FAMILIA VARCHAR(15) CHARACTER SET NONE DEFAULT '' COLLATE NONE,
  CODIGO_ARTICULO VARCHAR(30) CHARACTER SET NONE NOT NULL COLLATE NONE,
  DESCRIPCION ART_NOMBRE DEFAULT '' NOT NULL,
  IMPORTE_UNITARIO NUMERIC(18, 2) DEFAULT 0,
  CANTIDAD CANTIDAD_FLOAT DEFAULT 0 NOT NULL,
  IMPORTE_IMPUESTO NUMERIC(18, 2) DEFAULT 0,
  PORC_IMPUESTO NUMERIC(6, 2) DEFAULT 0,
  GRAVADO CHAR(1) CHARACTER SET NONE DEFAULT 'N' NOT NULL COLLATE NONE,
  IMPUESTO_INCLUIDO CHAR(1) CHARACTER SET NONE DEFAULT 'N' NOT NULL COLLATE NONE,
  TIENE_SERIES CHAR(1) CHARACTER SET NONE DEFAULT 'N' NOT NULL COLLATE NONE,
  COMPROBANTE VARCHAR(12) CHARACTER SET NONE NOT NULL COLLATE NONE,
  IMPORTE_COSTO NUMERIC(18, 2) DEFAULT 0,
  IMPORTE_TOTAL NUMERIC(18, 2) DEFAULT 0,
  IMPORTE_DESCUENTO NUMERIC(18, 2) DEFAULT 0,
  PORC_DESCUENTO NUMERIC(6, 2) DEFAULT 0,
  FRACCIONADO CHAR(1) CHARACTER SET NONE DEFAULT 'N' NOT NULL COLLATE NONE,
  ID_FRACCION INTEGER DEFAULT 0,
  FRACCION CANTIDAD_FLOAT DEFAULT 0 NOT NULL,
  COMPUESTO CHAR(1) CHARACTER SET NONE DEFAULT 'N' COLLATE NONE,
  ANULADA CHAR(1) CHARACTER SET NONE DEFAULT 'N' NOT NULL COLLATE NONE,
  FK_PROVEEDOR INTEGER,

Ahora tengo esta consulta para traer los siguientes datos de la tabla de Inventario:

Código SQL [-]
SELECT DISTINCT NOMBRE2, CODIGO3 FROM INVENTARIO WHERE NOMBRE2 IS NOT NULL AND CODIGO3 IS NOT NULL
order by nombre2

y esta es la consulta que realizo en la tabla de DETALLE_FACTURAS:

Código SQL [-]
    select DETALLE_FACTURAS.CODIGO_ARTICULO,
         DETALLE_FACTURAS.DESCRIPCION,
         DETALLE_FACTURAS.CANTIDAD,
         DETALLE_FACTURAS.IMPORTE_UNITARIO,
         detalle_facturas.IMPORTE_TOTAL,
         detalle_facturas.IMPORTE_DESCUENTO,
         (detalle_facturas.IMPORTE_TOTAL-detalle_facturas.IMPORTE_DESCUENTO) TOTAL_VENTA
  from DETALLE_FACTURAS where detalle_facturas.CODIGO_ARTICULO = :pCodigo AND DETALLE_FACTURAS.FECHA between :FechaInicio and :FechaFin
   GROUP BY DETALLE_FACTURAS.CODIGO_ARTICULO, 
            DETALLE_FACTURAS.DESCRIPCION,
            DETALLE_FACTURAS.CANTIDAD,
            DETALLE_FACTURAS.IMPORTE_UNITARIO,
            detalle_facturas.IMPORTE_TOTAL,
            detalle_facturas.IMPORTE_DESCUENTO,
            TOTAL_VENTA

Ahora necesito es consultar por el CODIGO3 ya que este código se repite en varios productos o sea el codigo3 puede estar 50 articulos vendidos y hacer su respectiva sumas de totales..

ah... la BD esta en el mismo servidor... y es firebird 2.5...

creo que me explique mejor... :D

Saludos

Casimiro Notevi 10-01-2013 18:43:10

Entonces, según dices, esas tablas pertenecen a bases de datos distintas.

Al González 10-01-2013 18:44:01

Cita:

Empezado por novato_erick (Mensaje 453191)
El Administrador de proyectos anterior había sugerido utilizar una base de datos para cada sistema ejemplo:

Inventario, Ventas, Planilla, Contabilidad desconozco porque la sugerencia [...]

¡Tremenda metida de pata de ese administrador! :eek:

¿Qué posibilidades tienes de unirlas en una sola? :)

novato_erick 10-01-2013 18:45:22

Cita:


Casimiro Notevi:
Entonces, según dices, esas tablas pertenecen a bases de datos distintas.
Así es... Las tablas que consulto están en dos base de Datos Diferentes dentro del mismo servidor de Base de Datos

novato_erick 10-01-2013 18:50:22

Cita:

Al Gonzalez:
¡Tremenda metida de pata de ese administrador!

¿Qué posibilidades tienes de unirlas en una sola?
En realidad se está trabajando en eso o sea se esta unificando todo sin embargo esta en desarrollo pero me toco a mi ir ya nadando con el río ya que esa fue una aplicación que habían desarrollado y esta hace 3 años en producción y necesitan información...

Saludos Al Gonzalez..

Casimiro Notevi 10-01-2013 19:56:28

En lugar de hacerlo con "execute stament", también puedes usar el método "clásico", tener 2 conexiones distintas, una a cada base de datos, ya sabes.
Puedes traerte los datos de una y meterlos en una tabla en memoria, luego consultas en la otra base de datos y "mezclas" los datos con los existentes en la tabla en memoria.

novato_erick 10-01-2013 20:30:15

Ok te entiendo Casimiro Notevi

Entonces si utilizo conexiones con componente por ejemplo DBExpress ya estaria cerrando este hilo y pasándolo a otro?


Saludos...

Casimiro Notevi 10-01-2013 20:36:40

Puedes seguir aquí, se trata de resolver un problema/duda y estamos con el mismo problema/duda, no es ninguna duda distinta, supongo.
Pero si vas a preguntar cómo funciona dbexpres o algo así, entonces es mejor en otro hilo, para que se pueda ver por el título de qué trata.

novato_erick 10-01-2013 20:54:45

Cita:

Casimiro Notevi:
Puedes seguir aquí, se trata de resolver un problema/duda y estamos con el mismo problema/duda, no es ninguna duda distinta, supongo.
Pero si vas a preguntar cómo funciona dbexpres o algo así, entonces es mejor en otro hilo, para que se pueda ver por el título de qué trata.
para nada no voy a preguntar como funciona realice lo siguiente:

dos Conexiones TsqlConnection uno para la dbInventario y otra para dbVentas
dos TsqlQuery el cual:
qConsultaArancel tiene en su propiedad SQL lo siguiente y conectado a inventario:
Código SQL [-]
select  I.COD_BARRAS, i.CODIGO3, i.NOMBRE2,  i.PESONETO from INVENTARIO i where i.CODIGO3 =:Arancel
group by i.COD_BARRAS, i.CODIGO3, i.NOMBRE2, i.PESONETO

qConsultaVentaFactura tiene en su propiedad SQL y conectado a ventas:
Código SQL [-]
    select DETALLE_FACTURAS.CODIGO_ARTICULO,
         DETALLE_FACTURAS.DESCRIPCION,
         DETALLE_FACTURAS.CANTIDAD,
         DETALLE_FACTURAS.IMPORTE_UNITARIO,
         detalle_facturas.IMPORTE_TOTAL,
         detalle_facturas.IMPORTE_DESCUENTO,
         (detalle_facturas.IMPORTE_TOTAL-detalle_facturas.IMPORTE_DESCUENTO) TOTAL_VENTA
  from DETALLE_FACTURAS where detalle_facturas.CODIGO_ARTICULO = :Codigo AND DETALLE_FACTURAS.FECHA between :FechaInicio and :FechaFin
   GROUP BY DETALLE_FACTURAS.CODIGO_ARTICULO, 
            DETALLE_FACTURAS.DESCRIPCION,
            DETALLE_FACTURAS.CANTIDAD,
            DETALLE_FACTURAS.IMPORTE_UNITARIO,
            detalle_facturas.IMPORTE_TOTAL,
            detalle_facturas.IMPORTE_DESCUENTO,
            TOTAL_VENTA

Entonces tengo ya este codigo que me trae la información poniendolos hasta en tres ClientDataSet:

Código Delphi [-]
procedure TfrmSecundario.Button1Click(Sender: TObject);
Var
  i: integer;
begin
  begin
    CodArancel := trim(Edit1.Text);
    dmLogica.cdsInventarioConsulta.Close;
    with dmConecta.qConsultaArancel do
    begin
      Close;
      ParamByName('Arancel').AsString := CodArancel;
      open;
    end;
    dmLogica.cdsInventarioConsulta.open;
    i := dmLogica.cdsInventarioConsulta.RecordCount;
    Edit2.Text := IntToStr(i);   // para conocer en el edit la cantidad de registros devueltos
  end;
  dmLogica.cdsInventarioConsulta.First;
  for i := 1 to dmLogica.cdsInventarioConsulta.RecordCount do
  begin
    dmLogica.cdsConsultaVentaFacturas.Close;
    begin
      CodBarra := dmLogica.cdsInventarioConsultaCOD_BARRAS.AsString;
      NomArancel := dmLogica.cdsInventarioConsultaNOMBRE2.AsString;
      with dmConecta.qConsultaVentaFactura do
      begin
        Close;
        ParamByName('Codigo').AsString := CodBarra;
        ParamByName('FechaInicio').AsDateTime := dtpInicioFecha.DateTime;
        ParamByName('FechaFin').AsDateTime := dtpFinalFecha.DateTime;
        open;
      end;
      dmLogica.cdsInventarioConsulta.Next;
      dmLogica.cdsConsultaVentaFacturas.open;
    end;
    dmLogica.cdsAgregaValorFacturas.AppendData
      (dmLogica.cdsConsultaVentaFacturas.Data, True);
  end;
end;

al final el ClientDataSet llamado cdsAgregaValorFacturas recibe un AppenData de mi cdsConsultaFActuraVentas.Data ya que como dije en el pos un codigo3 puede estar con 50 articulos diferentes... pero al final la información se va a reducir en esto: (es aquí donde estoy trabado)

Cita:

TInventario--------TInventario-------TDFactura--------TInventario--------TDFactura
Codigo3------------nombre2 ---------cantidad---------PesoTotal----------Totalventa
800231----------- Cocinas ---------- 50 ------------ 420 ---------- 4,200.00

Casimiro Notevi 10-01-2013 21:23:44

¿Pero cual es el problema?


Por cierto, a esto:
Código Delphi [-]
    select DETALLE_FACTURAS.CODIGO_ARTICULO,
         DETALLE_FACTURAS.DESCRIPCION,
         DETALLE_FACTURAS.CANTIDAD,
         DETALLE_FACTURAS.IMPORTE_UNITARIO,
         detalle_facturas.IMPORTE_TOTAL,
         detalle_facturas.IMPORTE_DESCUENTO,
         (detalle_facturas.IMPORTE_TOTAL-detalle_facturas.IMPORTE_DESCUENTO) TOTAL_VENTA
  from DETALLE_FACTURAS where detalle_facturas.CODIGO_ARTICULO = :Codigo AND DETALLE_FACTURAS.FECHA between :FechaInicio and :FechaFin
   GROUP BY DETALLE_FACTURAS.CODIGO_ARTICULO, 
            DETALLE_FACTURAS.DESCRIPCION,
            DETALLE_FACTURAS.CANTIDAD,
            DETALLE_FACTURAS.IMPORTE_UNITARIO,
            detalle_facturas.IMPORTE_TOTAL,
            detalle_facturas.IMPORTE_DESCUENTO,
            TOTAL_VENTA
Al no haber involucrada ninguna otra tabla, le puedes quitar el "DETALLE_FACTURAS." a todos:
Código Delphi [-]
select CODIGO_ARTICULO, 
       DESCRIPCION,
       CANTIDAD,
       IMPORTE_UNITARIO,
       IMPORTE_TOTAL,
       IMPORTE_DESCUENTO,
       (IMPORTE_TOTAL-IMPORTE_DESCUENTO) TOTAL_VENTA
from DETALLE_FACTURAS 
where CODIGO_ARTICULO = :Codigo 
AND FECHA between :FechaInicio and :FechaFin
GROUP BY CODIGO_ARTICULO, 
         DESCRIPCION,
         CANTIDAD,
         IMPORTE_UNITARIO,
         IMPORTE_TOTAL,
         IMPORTE_DESCUENTO,
         TOTAL_VENTA


La franja horaria es GMT +2. Ahora son las 16:56:11.

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