Buscar clave en tipo "alfanumerico" y "numerico"

232 views
Skip to first unread message

Saúl Piña

unread,
Sep 23, 2014, 8:42:23 PM9/23/14
to publice...@googlegroups.com
Saludos comunidad,

Me han pedido que cambie el tipo de dato del campo "clave" (normalmente yo utilizo la clave de tipo "numerico" o "int" en mysql) y por eso no habia tenido problema alguno. ya que el "numerico" se lee con tan solo hacer:

Local cVar
cVar=thisform.txtclave.value
select clave from productos where clave=cVar into cursor Consultas


ahora bien, como puedo lograr que las claves "1000" , "c1000" , "100" , "100x" que el sistema lea exactamente la clave a buscar.

digamos que busco la clave "100" y el sistem me trae la clave "1000"  ese es todo mi problema. La manera que uso para buscar es la siguiente:

set exact on
Local cVar
cVar=upper(alltrim(thisform.txtclave.value))
select clave from productos where upper(allt(clave))=cVar into cursor Consultas


pero me devuelve otra clave que no es la que busco.  Como podría lograr buscar los alfanumericos.

muchas gracias por todo.




Saúl Piña

unread,
Sep 23, 2014, 8:48:56 PM9/23/14
to publice...@googlegroups.com
Ya funciona, de todas formas muchas gracias.

Antonio Meza

unread,
Sep 24, 2014, 2:05:39 PM9/24/14
to publice...@googlegroups.com
Aunque dices que ya lo solucionaste, te comento que en mi caso tengo mi campo ID de la tabla INT autoincremental primary key y luego uso 2 campos mas para guardar valores claves por ejemplo en facturación uso un campo SERIE y un campo FOLIO los dos con Varchar y de esta forma almaceno así

SERIE    FOLIO
F            0000000001
B            0000000001
NC         0000000001

Un error común es que muchos almacena en un solo campo por decir FOLIO la suma de los 2 valores, y queda algo así

FOLIO
F0000000001
F1
F001

En un futuro el usar esto si el cliente quiere usar mas dígitos para poner LETRAS, o mas o menos digitos para el FOLIO pues que pasa con los datos anteriores? o los ajustas o tu tabla te va a crear dolores de cabeza gratis jajaja

Y para buscar pues where Serie = ?campoSerie and Folio = ?campoFolio

Solo es algo que uso pensado en futuro, si lo tienes así pues creo que vas bien, si no pues velo como una recomendación.

saludos
Antonio Meza


El martes, 23 de septiembre de 2014 19:42:23 UTC-5, Saúl Piña escribió:

HernanCano

unread,
Sep 25, 2014, 1:47:34 AM9/25/14
to publice...@googlegroups.com
Con el SET EXACT ON (que ya estaba incluido cuando preguntaste) debería funcionar, pero te recomiendo doble igual y sin EXACT, así:


select CLAVE from PRODUCTOS where upper(alltrim(CLAVE))==upper(alltrim(ThisForm.txtClave.Value)) into cursor Consultas


Tip:
La base de toda mi respuesta es que (1) sí uses doble igual, y (2) no es necesario el SET EXACT ON (o sea que el SET EXACT puede estar en ON o en OFF: no afecta --para el doble igual--)

Tip:
Si usas un sólo igual, estás obligado a usar SET EXACT ON, de lo contrario fallará como mencionas (al buscar T10, se encuentran también T100 y T1000).


PREGUNTA:
¿Cuál fue la solución?
O es secreto de estado?



El martes, 23 de septiembre de 2014 19:42:23 UTC-5, Saúl Piña escribió:

Antonio.xt

unread,
Sep 25, 2014, 9:34:01 AM9/25/14
to publice...@googlegroups.com

Yo creo que la solucion mas simple y optima es crear un estandar para el formato de las claves alfanumericas, rellenandolo con ceros a la izquierda, asi no habria problemas con SET EXACT ON/OFF, ni con = o ==, todas las claves tendrian la misma longitud y serian unicas.

En una ocasion hace tiempo en un sistema, use ese metodo en todas las claves y nunca tuve problemas

Saludos...

Carlos Miguel FARIAS

unread,
Sep 25, 2014, 1:58:45 PM9/25/14
to Grupo Fox
La razón de usar claves autoincrementales proviene de que en muchos sistemas se necesitan guardar registros de diferentes entidades relacionadas entre ellas (por ejemplo cabecera factura y su detalle.
La dificultad en estos casos, cuando hay concurrencia es que no se pueden usar datos propios de las entidades hasta que no se completo la transacción. Y por eso recurrimos a esas PK artificiales.
Por ejemplo: Facturacion. Usuario 1 inicia factura con 15 items, empieza a cargar, usuario 2 inicia factura con 2 items, empieza a cargar. Si se usaran tipo, sucursal y numero para identificar la factura (estilo Argentina), puede darse que el usuario 2, que empezó después, tendría número posterior y termina antes que usuario 1, y ni te cuento si usuario 1 además cancela (se pierde el número).
Entonces se recurre a los autoincrementales, al insertar se crea y numera, y ese número (PK) se usa como foránea (FK) en tabla relacionada.
Si usamos un autoincremental de 32 bits posiblemente no tengamos muchas alternativas, pero si pensamos en uno de 64 bytes (un serial grande en algunos SGBD), con esa cantidad de dígitos podemos pensar en muchas cosas interesantes a guardar, en lugar de ser un simple numerador. Son +/- 19 dígitos que nos permitirían guardar mucha información aprovechable. Fecha, y hora al milésimo y muchos otros datos (#usuario, #pc, etc), y es mucho más aprovechable que un simple timestamp.. Y ambos ocupan 8 bytes en disco.
Y con ese sistema, si se generan datos en máquinas separadas, se podrán unir los datos sin conflictos.
Saludos: Miguel, La Pampa (RA)

Antonio Meza

unread,
Sep 25, 2014, 3:20:56 PM9/25/14
to publice...@googlegroups.com
Hola Miguel 

Justo lo que comentas es el problema real que existe, que la mayoría de los programadores confunde un numero de código o folio con un identificador de registro. Por lo tanto los PK (Primary Key) se usan para diferenciar un registro de otro y a demás para relacionar con otras tablas, permitiendo que las sentencias SQL sean sencillas y optimizadas, si no usan este principio básico pues no están usando las bondades del motor de base de datos, pero como todo en el mundo hay excepciones habría que analizarlas.

Una factura (tabla cabecera) lo natural es que tenga una clave PK, que identifique el registro y a demás tenga un código o folio de factura, pero el error que algunos comenten es usar este código o folio para relacionarlo con otra tabla e incluso usarlo como si fuera el PK y de ahí los problemas de sistema multiusuario, el control de los folio y muchas cosas que se evitan si entienden y aplican el concepto del PK

Una tabla normalizada de factura seria algo así
id (pk)
idsucursal (FK)
folio varchar

Una tabla normalizada de detalle de factura seria así
id (pk)
idFactura (FK id de la tabla factura)

El error común es que lo hacen así

factura
idsucursal (FK)
folio varchar o int

detalle
idsucursal (FK)
idFolio varchar o int

Y otro error incluso cuando usan PK algo así

factura
id (pk)
idsucursal (FK)
folio varchar o int

detalle
id (pk)
idsucursal (FK)
idFolio varchar o int


Como puedes ver al usar Folio como campo relacionado tienes que forzosamente usar el campo de la Sucursal ya que el Join estaría incorrecto puesto que mostraría todas las factura de varias sucursales que el folio sea el mismo, otro pequeño error es usar el campo Folio como numérico, si bien no lo vas a usar para sumar ni restar debería ser carácter o alfanumérico y rellenarlo con Ceros a la izquierda para un mejor ordenamiento y búsqueda.

Respecto a poner todos los huevos en una sola canasta difiero un poco, me refiero a usar un PK mas complicado para proveerme mas información, nuevamente volvemos a caer en la mala interpretación de lo que es un simple identificador a lo que es un código, si me dices que es mejor usar una clave primaria que me permita a simple vista o me permita obtener mas información creo que estamos generando en un principio que la consulta sea mas lenta porque el valor de comparación sera mas grande, si lo que se trata es de optimizar y otro campo me puede dar lo que necesito entonces para que mezclar la función de un identificador con la función de información? es decir el PK solo es y debería usarse para identificar y relacionar un registro pero no que el mismo PK me permita saber que contiene ese registro no se si me explico la idea, es mas el usuario no tiene ni porque saber de la existencia de un PK.

Trabajo mucho con Agencias Aduanales, ellos maneja la famosa REFERENCIA que es un consecutivo del cual muchos agentes aduanales hacen mal uso de este código de identificación, ya que por ejemplo quieren que al ver la Referencia sepan si es una Importación o exportación, de que patente es, de que aduana es, de que cliente es, y volvemos a caer en el concepto equivocado para que son las cosas.

Entonces imaginen que tengo IMP = IMPORTACIÓN, MÉXICO es la aduana 470, el cliente se llama Juan Perez, y la patente es la 9999, entonces me eh llevado la sorpresa de ver referencias así IMP430JUANPEREZ9999-00001 y es valido porque no requieres entrar al sistema para saber de quien es de que aduana es que tipo de operación es, pero no seria mas fácil las 3 iniciales de la aduana MEX dos dígitos del año 99 y un consecutivo algo así MEX99-00001, que visualmente no me dará mucha información pero entonces para que esta el sistema, incluso puede ser un folio consecutivo 0000001111 y con eso debe bastar, entro al sistema tecleo el codigo o folio o referencia y ya veo de quien es, de donde es y que tipo es etc etc etc.

Me puedo ampliar mas pero el PK es para identificar y relacionar solamente, el código o folio es para informar si lo vemos de manera fácil.

saludos
Antonio Meza





saludos
Antonio Meza

Víctor Hugo Espínola Domínguez

unread,
Sep 25, 2014, 3:40:30 PM9/25/14
to publice...@googlegroups.com
Hola Antonio

El ejemplo de Facturas es correcto para una base de datos centralizada, para bases de datos distribuidas puedes mirar este enlace: http://blogs.msdn.com/b/dfurman/archive/2009/08/30/surrogate-keys-in-distributed-databases.aspx

Allí se aplica lo que estaba comentando Miguel.

Saludos,
Víctor.
Lambaré - Paraguay.

Carlos Miguel FARIAS

unread,
Sep 25, 2014, 3:53:20 PM9/25/14
to Grupo Fox
Es correcto lo que plantea Antonio y Victor documenta lo que yo indicaba.
Las PKs deben proveer identificación univoca y minima de cada instancia (fila, tupla, registro) en cada entidad (tabla, archivo, blableta). En bases distribuidas, al sincronizar los autoincrementales fallan, además es un dato que no aporta nada.
Y además son números que desperdician capacidad de datos (un entero soporta 9 dígitos, tienes 1 gigabyte de registros REGISTROS; no bytes). Si no es así, hay dígitos que nunca se utilizaran. Si entra un registro por segundo, necesitas 22000 días para llenar la tabla (y dentro de 60 años quisiera estar, darme cuenta disfrutarlo pero no estar trabajando!!!!)
Un autoincremental es un secuencia de números de enteros, que solo sirven para relacionar tablas (en forma óptima) pero no sirven para más nada, y en distribuidas tal como se indica, no funcionan.
Por eso mi propuesta es meter en las pk, algún dato que me sirva para establecer orden de carga, fulano responsable y lugar donde metió los garfios (me sale el auditor de adentro aaaag!)
Y eso es, de otra manera lo que sugieren en el articulo que menciona Victor.

Cada 102 programadores 1 son la mitad.

Saludos: Miguel, La Pampa (RA)

Antonio Meza

unread,
Sep 25, 2014, 4:20:37 PM9/25/14
to publice...@googlegroups.com
Hay que diferenciar dos cosas claramente!!

1.- El tema fundamental que comento es el error de usar los PK (claramente en bases de datos que no van hacer distribuidas) ahora si este error lo comenten en bases de datos normales imaginen los escenarios que tendrán si quieren hacerla distribuida

2.- Los PK solo son y sirve para identificar un registro y relacionar, no debemos tomarlos en cuenta para otra cosa, de que se pueden hacer muchas cosas se pueden, pero incluso en el articulo que menciona Miguel, se comenta que no es optimo lo que proponen ahí, entonces que beneficio hay? hacer mas fácil la programación o hacer mas optimas las consultas? yo en lo personal buscaría optimizar las consultas, porque claramente lo he sabido que usar GUID para simular un PK o relacionar no es optimo, es mas una comodidad del programador y es exactamente lo que proponen en el articulo solo que usando una combinación de dígitos mas natural, pero esa generación no es optima al final.

Seria muy tonto de mi parte opinar mas sobre los PK en el caso de bases de datos distribuidas puesto que nunca los eh usado, por lo pronto mi intensión es que muchos aprendan a diseñar una base de datos lo mas optima posible y dejar los malos usos que nos permitían los DBF. ya ampliar el tema sobre distribución estoy virgen en el tema.

saludos
Antonio Meza

Carlos Miguel FARIAS

unread,
Sep 25, 2014, 4:35:50 PM9/25/14
to Grupo Fox
El articulo no lo comente yo, fue Victor, y la solución que dan ahi, no es la que doy yo.
En el articulo mencionan un campo de id de origen de datos (bd) mas un autoincremental local.
O sea hablan de dos atributos, uno generado por el SGBD y otro propio, que en si salvo el id de sucursal no aportan información al sistema (salvo origen de datos).
Lo que indico es una alternativa, es un campo calculado conformado por datos que pueden ser reaprovechados, además de su función de PK, para manejar datos de auditoria.
O sea, no estoy poniendo en tela de juicio lo que plantea Antonio, conceptualmente correcto y si se probó y funciona bien no debe modificarse; propongo una forma de generar pk únicas que además me indican donde, quien y cuando, o sea obtengo orden cronológico, y datos para auditoria. Y esa misma función puedo usarla en un campo aparte, para indicar cuando, quien y donde el registro fue modificado. 
Cada cual verá que se adapta mejor a su negocio.
Saludos: Miguel, La Pampa (RA)

Antonio Meza

unread,
Sep 25, 2014, 4:51:27 PM9/25/14
to publice...@googlegroups.com
Tienes razón error de nombre fue Victor!!

Y retomando lo que comentas Miguel, si lo entendí claramente, es darle vida al PK dejar de ser un simple identificador y que sea a su ves un informador (chismoso jajaja) y que a demás puede ser usado en bases distribuidas.

Solo que esta solución al igual que los GUID y lo que comentan en el link de Victor no son optimas, pero si funcionan claramente y le hacen la vida mas fácil al programador, por eso decía que se sacrifica rendimiento por facilidad de programación.

En mi caso voy a estudiar mas a fondo estos temas porque me interesa que mi sistema tenga la opción de poder distribuir la base de datos y como esta actualmente usando PK simples ya me quedo claro que no sera tan fácil, aun que depende del escenario y tipo de replicación de datos.

saludos
Antonio Meza

Carlos Miguel FARIAS

unread,
Sep 25, 2014, 6:46:26 PM9/25/14
to Grupo Fox
Antonio: ¿Que le vez de compleja o no optima a la pk que indico? Es un entero largo (64 bits -> 8 bytes). No un GUIDs de 16 bytes
Y lo calculas con una función de un renglón.
No es tan potente como un GUIDs pero maneja un rango aceptable de identificadores.
En realidad es un GUIDs simplificada (ver: http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt)
Saludos: Miguel, La Pampa (RA)
Reply all
Reply to author
Forward
0 new messages