www.clarioneros.com

El rincón de los desarrolladores
Fecha actual Vie Oct 20, 2017 6:01 pm

Todos los horarios son UTC




Nuevo tema Responder al tema  [ 5 mensajes ] 
Autor Mensaje
NotaPublicado: Vie Sep 28, 2012 11:37 am 
Desconectado
Avatar de Usuario

Registrado: Dom Feb 06, 2011 9:34 am
Mensajes: 1008
Ubicación: España
Hace unos días me contactó Ramón Pacheco para consultarme sobre una conversión a SQL que está encarando. Me envió la estructura de algunas de las tablas involucradas y me preguntaba cómo hacer las relaciones de las mismas en el SQL. Como el caso me pareció interesante le pedí permiso para responderle a través del foro así todos podían leer las sugerencias y opinar sobre las mismas.
Como es un sistema de facturación hay, básicamente, 4 tablas involucradas: Facturas, DetalleFacturas, Clientes y Productos.

Estas son sus estructuras:
Tabla
Clientes

Campo tipo longitud Llave
Código Int Identy 4 codigoKey Unico Primaria
Nombres nvarchar (100) NombrKey IndexeKey
Direccion nvarchar (100)
Sector nchar (60)
Ciudad nchar (50)
Telefono nvarchar (125)
Email nvarchar (125)
Estatus nchar (8)
Saldo numeric (18, 2)


Tabla
Productos

Campo tipo longitud Llave
Codigo Int Identy 4 codigoKey Unico Primaria
Envases nchar (15)
Lineas nchar (20)
Descripción nvarchar (100) DescrKey IndexeKey
Marca nchar (20)
Precios_Unitario numeric (17, 2)
Existencia_Maxima real
Existencia_Minima real
Reorden real


Tabla
Factura

Campo tipo longitud Llave
NroFactura Int Identy 4 codigoKey Unico Primaria
Fecha Date
Condiciones nchar (20) CondicioKey IndexeKey
CodigoClie int 4 CodigoClieKey IndexeKey
Monto numeric (17, 2)
ControlImpresion Real
Renglón Real

Tabla
DetalleFactura

Campo tipo longitud Llave
NroFactura Int Identy 4 codigoKey Unico Primaria
Envases nchar (15)
CodigoPro Int (4) CodigoProKey IndexeKey
Cantidad Real
Precios_Unitario numeric (18, 2)
Importe numeric (18, 2)


Las relaciones serán: Facturas -->> DetalleFacturas
Clientes-->> Facturas
Productos -->> DetalleFacturas

Donde -->> representa una relación 1 a Muchos.

A primera vista hay algo que está mal. En la tabla DetalleFacturas el NroFactura no puede ser clave única porque en ese caso solo podríamos tener una sola línea por cada factura lo cual no sería muy práctico. Cambiando este índice podríamos entonces establecer la relación pero es importante, en SQL, que cada tabla tenga un índice único, así que hay que tener en cuenta esto.

Aunque esto es algo particular a mí me gusta tener un campo ID, Identity en SQL, que sé que será único e intocable, para establecer las relaciones. Si analizamos este ejemplo, el código de Cliente está definido de esta forma. Pero eso significa que el usuario jamás podrá cambiar ese código, será el sistema quien lo asigne y lo hará recién una vez confirmada la carga (el IDENTITY se establece en el momento de la grabación, no antes). Qué pasa si uno de nuestros clientes quiere un campo alfanumérico para el código? Y si no le gusta el número generado y quiere remplazarlo por otro? (por más extraño que esto parezca seguramente les habrá pasado más de una vez). Para evitar ese tipo de casos lo que hago es tener 2 campos:
ClienteID INT Identity
ClienteCodigo (lo que sea, puede ser numérico, alfanumérico)

Las relaciones de esta tabla con otras (Facturas, por ejemplo) la hago a través del campo ClienteID. El usuario del sistema ni siquiera se entera de la existencia de este campo, para él es invisible. La ventaja de esto es que si por algún motivo le quiere cambiar el código a su cliente lo puede hacer y la relación se mantendrá intacta. Si no hacemos esto puede darse el caso de que tengamos un cliente con miles de facturas y que, al cambiar su código, debamos actualizar en cascada esas miles de facturas, lo que solo hará más lento a nuestro sistema.

Una vez establecido esto hago lo mismo con las otras tablas, creando en todas ellas un campo ID (FacturaID, ProductoID, DetalleID).

Algo a tener en cuenta es la correspondencia entre los tipos de datos en TPS y SQL. Las nuevas versiones de SQL incorporan nuevos tipos de datos y desgraciadamente Clarion siempre corre por detrás de eso. Nos tenemos que manejar con lo que tenemos, que básicamente es:

Tipo de dato en Clarion Equivalente en SQL
string char
cstring varchar
byte tinyint
short smallint
long int
date date
time time
datetime group
pdecimal decimal

A menos que sepamos que un campo de caracteres es de longitud fija y no va a cambiar (por ejemplo, 1 caracter para identificar el sexo de una persona) prefiero trabajar con los varchar.

En la próxima entrada seguiré con la conversión.

_________________
Mauricio, básicamente usando Clarion 6.3
www.tdcsoftware.com y www.clarioneros.com/blog


Arriba
 Perfil Email  
 
NotaPublicado: Dom Oct 11, 2015 5:44 am 
Desconectado

Registrado: Dom Feb 06, 2011 9:43 pm
Mensajes: 67
Ubicación: Montevideo - Uruguay
Hola Mauricio, tengo una duda, estoy migrando a Firebird y a todas las tablas les agregué un campo ID Int autonumerado, la duda es que en las facturas por rj. selecciono el cliente y guardo su número o sea que sería el campo que podría ser alfanumérico, si tengo definido el ID como la clave primaria y es el que voy a utilizar para relacionar la tabla clientes con facturas como hago para que al seleccionar el cliente por el número me guarde el ID de cliente en la tabla Facturas, no sé si se entiende.
Saludos !


Arriba
 Perfil Email  
 
NotaPublicado: Dom Oct 11, 2015 6:41 am 
Desconectado
Avatar de Usuario

Registrado: Dom Feb 06, 2011 9:34 am
Mensajes: 1008
Ubicación: España
No entendí mucho la verdad. En la tabla facturas tenés el ID del cliente, el campo autonumerado, no? Bueno, al seleccionar el cliente en el form de Facturas lo único que tenés que hacer es poner FAC:IdCliente = CLI:IdCliente. El browse de selección de Clientes tiene que tener ese campo al menos como hotField.
Si en el form de Facturas tenés el código del cliente (no el autonumerado sino el código que el usuario sabe) lo que tenés que hacer es poner en el Entry algo así:
Código:
CLI:Codigo = Loc:CodigoCliente ! Loc:CodigoCliente es una variable
IF Access:Clientes.TryFetch(CLI:xCodigoCliente) = Level:Benign
     FAC:IdCliente = CLI:IdCliente
ELSE
     Message('Código cliente inexistente')
END !IF

_________________
Mauricio, básicamente usando Clarion 6.3
www.tdcsoftware.com y www.clarioneros.com/blog


Arriba
 Perfil Email  
 
NotaPublicado: Dom Oct 11, 2015 8:45 pm 
Desconectado

Registrado: Dom Feb 06, 2011 9:43 pm
Mensajes: 67
Ubicación: Montevideo - Uruguay
Si es justamente eso, digo en TPS tenía un campo Cliente como LONG que era la clave primaria y única pero justamente el usuario podía modificarlo cuando se ingresaba una factura había un Field LookUp y se seleccionaba el cliente. La duda era esa que al ocultar justamente el ID al usuario en la interfaz debo usar código a mano para guardarlo en la tabla facturas.
Saludos !


Arriba
 Perfil Email  
 
NotaPublicado: Dom Oct 11, 2015 9:36 pm 
Desconectado
Avatar de Usuario

Registrado: Dom Feb 06, 2011 9:34 am
Mensajes: 1008
Ubicación: España
Si, entiendo, entonces en ese caso no te queda otra que usar una variable y asignarla. Es un poco más molesto pero ganás en seguridad y velocidad.

_________________
Mauricio, básicamente usando Clarion 6.3
www.tdcsoftware.com y www.clarioneros.com/blog


Arriba
 Perfil Email  
 
Mostrar mensajes previos:  Ordenar por  
Nuevo tema Responder al tema  [ 5 mensajes ] 

Todos los horarios son UTC


¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado


No puede abrir nuevos temas en este Foro
No puede responder a temas en este Foro
No puede editar sus mensajes en este Foro
No puede borrar sus mensajes en este Foro
No puede enviar adjuntos en este Foro

Saltar a:  
Powered by phpBB® Forum Software © phpBB Group
Traducción al español por Huan Manwë para phpbb-es.com