[VFP] Como generar un numero único a partir de la fecha

3,174 views
Skip to first unread message

ZeRoberto

unread,
Jan 7, 2013, 9:37:56 PM1/7/13
to publicesvfoxpro

El comando sys(2015) genera un nombre de procedimiento único en base a la fecha, como puedo generar un numero unico basándome en ese principio.

Por ejemplo

Año = 2013
Mes = 1
Dia = 7
Hora = 9
Min = 36
Sec = 36
MiliSec = 235

Numero = 2337

Osea la suma de todos los parametros

Pero no tengo MiliSegundos no se como sacar esa info

Saludos

Luis Maria Guayan

unread,
Jan 7, 2013, 10:07:25 PM1/7/13
to publice...@googlegroups.com
? VAL(TTOC(DATETIME(),1) + TRANSFORM(MOD(SECONDS(),1)*1000, "@L 999"))

Luis María Guayán
Tucumán, Argentina
_________________________
http://www.PortalFox.com
Nada corre como un zorro
_________________________

--
 
 

mpulla

unread,
Jan 7, 2013, 10:08:13 PM1/7/13
to publice...@googlegroups.com
Hola Roberto.

Me parece que trabajas con MySql, manda al servidor la sentencia

Esta sintaxis esta en Sql Server

declare @t datetime = getdate()
Select Cast(@t as decimal(18,12))
41279.918214699072


Saludos.
Mauricio

Rafael Morales

unread,
Jan 7, 2013, 10:16:28 PM1/7/13
to publice...@googlegroups.com
No te serviría de nada los milisegundos ya que hay muchas formas de llegar a un numero mediante la suma, por ejemplo el numero 2337 se puede formar también de esta manera:

Año = 2013
Mes = 2
Dia = 6
Hora = 9
Min = 36
Sec = 36
MiliSec = 235

Numero = 2337

Yo creo que deberías buscar por otro lado por ejemplo con: right(sys(2015),9)  te devuelve algo como esto 1F2OKP5Y8   de acuerdo a este resultado le asignas un numero a las letras (ej. F=1 , O=2, K=3, P=4, Y=5) y luego formas el numero final sin sumarlos (ej. 112234558 ). Pero obtendrías un numero muy largo,

Bueno esa es mi opinión, Quizas sirva de algo. Saludos.


--
Rafael Morales

Mariano Pinto Castro

unread,
Jan 8, 2013, 6:08:27 AM1/8/13
to publice...@googlegroups.com
Esto generala misma suma
Año = 2013
Mes = 2
Dia = 6
Hora = 9
Min = 36
Sec = 36
MiliSec = 235

--
 
 

Luis Maria Guayan

unread,
Jan 8, 2013, 11:31:46 AM1/8/13
to publice...@googlegroups.com
Dos opciones mas que te generan un número único a partir de la fecha hora de la pc y quizas mas comprimida (menos dígitos)

? VAL(SUBSTR(TTOC(DATETIME(),1),3) + TRANSFORM(MOD(SECONDS(),1)*1000, "@L 999"))

El formato es AAMMDDHHMMSSmmm (Año, Mes, Dia, Hora, Minuto, Segundo, Milisegundo

? VAL(SYS(1)+TRANSFORM(SECONDS()*1000, "@L 99999999"))

El formato es JJJJJJJSSSSSMMM (Dia a juliano de la fecha, Segundos de sde la medianoche, Milisegundos)


Luis María Guayán
Tucumán, Argentina
_________________________
http://www.PortalFox.com
Nada corre como un zorro
_________________________

Rafael Morales

unread,
Jan 8, 2013, 11:38:08 AM1/8/13
to publice...@googlegroups.com
Excelente!!! muy bueno.


--
Rafael Morales

ZeRoberto

unread,
Jan 8, 2013, 2:29:34 PM1/8/13
to publice...@googlegroups.com
Gracias a todos por las ideas, están buenas pero quiero que el numero sea mas corto.

Cuando meto al seconds() en un FOR de 20 veo que el SECONDS() se repite pero el SYS(2015) no se repite como se logra eso

Saludos

--
 
 

Luis Maria Guayan

unread,
Jan 8, 2013, 2:58:32 PM1/8/13
to publice...@googlegroups.com
ZeRoberto que es lo que necesitas hacer? Quizás te podamos ayudar con otra idea.


Luis María Guayán
Tucumán, Argentina
_________________________
http://www.PortalFox.com
Nada corre como un zorro
_________________________

--
 
 

ZeRoberto

unread,
Jan 8, 2013, 3:02:43 PM1/8/13
to publice...@googlegroups.com
Lo que quiero es 

tengo una tabla de productos, en caso de que el usuario no quiera ingresar un código esto se genere en base a la primera letra de la Familia +Marca y un numero único para evitar que se repita.

Solo es para evitar duplicidad

Saludos



--
 
 

Luis Maria Guayan

unread,
Jan 8, 2013, 3:12:15 PM1/8/13
to publice...@googlegroups.com
Mira, este artículo te puede ayudar

-- Números consecutivos para nuestras tablas  --
http://www.portalfox.com/article.php?sid=1466

Tienes una tabla para los Codigos de tus productos y cuando necesites uno, solo llamas a la función NuevoId()

Al valor retornado le agregas las letras que tu indicas y lo justificas con ceros a la izquierda

Ej:
lnCodigo =
NuevoId("PRODUCTOS")

lcCodigo = "F" + "M" + TRANSFORM(lnCodigo, "@L 999999")


Luis María Guayán
Tucumán, Argentina
_________________________
http://www.PortalFox.com
Nada corre como un zorro
_________________________

--
 
 

Armando Rodríguez Bermúdez

unread,
Jan 8, 2013, 3:12:20 PM1/8/13
to publice...@googlegroups.com

AMarca000001

AMarca000002

AMarca000003

 

Tendrías para 999,999 Productos de una Familia y Marca

--
 
 

Miguel Antúnez

unread,
Jan 8, 2013, 3:19:56 PM1/8/13
to publice...@googlegroups.com
Hace muy buen tiempo que ya no genero códigos (PK Primary Key) de esa forma. prefiero usar los auto-incrementales que vienen en las bases de datos, inclusive las tablas de VFP tienen esa particularidad. y para evitar la duplicidad de aquellos campos que necesito controlarlos, como un Nro de factura, Guias,etc.
en SQL Server utilizo los indices tipo Unique, una restricción similar en los DBF's, son las claves CANDIDATE.

Saludos.


--
 
 



--
Miguel Angel Antúnez Camones
mant...@gmail.com

Víctor Hugo Espínola Domínguez

unread,
Jan 8, 2013, 3:46:29 PM1/8/13
to publicesvfoxpro
Hola ZeRoberto

Puedes convertir a hexadecimal la solución sugerida por Luís María:

? SUBSTR(TRANSFORM( VAL(SYS(1)+TRANSFORM(SECONDS()*1000, "@L 99999999")), "@0"),3)

Si lo quieres más corto aún, convierte a base 32 o base 64, pero para eso debes escribir tu función, o buscarla por ahí.

Saludos.
Víctor.
P.D.: Creo que el consejo de Miguel Antúnez es lo más apropiado.



--
 
 

Dante

unread,
Jan 8, 2013, 3:58:39 PM1/8/13
to publice...@googlegroups.com
mmm... Particularmente no recomiendo usar Auto-incrementables como PK, de preferencia deben ser generados por Uno mismo(ya sea desde una tabla de PKs, count de la tabla u otro metodo).
La pregunta es porque? cuando alguna vez migres tus tablas ya sea hacia otro motor de base datos ahi viene un problema entre las relaciones de las tablas o cuando existen errores en las transacciones por X motivos, el autoincrementable  se pierde y si vuelven a generar la transaccion ese nro ya se perdio, no llevando asi un consecutivo real para una auditoria futura.

tampoco es recomendable que los PK sean parte del negocio, deben ser indiferentes a esto.

saludos,

Miguel Antúnez

unread,
Jan 8, 2013, 4:18:59 PM1/8/13
to publice...@googlegroups.com
Una apreciación muy distinta y distante, ya que llevo años trabajando bajo esta forma, nunca he tenido problemas, tampoco en las migraciones ya que se puede activar y desactivar los incrementales en cualquier momento, por el tema de la auditoria no hay ningún problema, tengo como política no eliminar registros, y la política de que  un registro solo puede ser modificado por otro registro. 
El tema de la perdida por las transacciones tampoco los veo como problemas, ya que un código solo representa al registro. y no representa mas que eso. No hay que olvidar que las creación de los códigos fue para simplificar la digitación y el espacio de almacenamiento, no para identificar un producto o algo similar, 

Saludos.

mpulla

unread,
Jan 8, 2013, 4:54:57 PM1/8/13
to publice...@googlegroups.com

Hola Miguel.

También trabajo con auto numéricos y al verdad no he tenido problemas, es cierto que por x motivos se cancela una transacción se pierde el secuencial, pero no le veo problema..

A lo que si le veo un poco molestoso es a la migración, actualmente estoy trabajando con Sql Server 2012 y los objetos Sequence que se dice que son más rápidos que los auto numéricos y su implementación muy simple.

Saludos.
Mauricio

ZeRoberto

unread,
Jan 8, 2013, 5:33:30 PM1/8/13
to publice...@googlegroups.com
Es que en algunas veces el usuario ya tiene codigos para buscar al menos en moto repuestos o en otros casos.
 
Ademas lo Autonumericos cuando sale un error el codigo ya se incremento en 1
 
Por eso quiero darle esta opcion de que el mismo pueda decidir si va a generar codigo o va a ser autonumerico pero yo mismo creo los autonumericos.
 
Saludos
 

 


--
 
 

ZeRoberto

unread,
Jan 8, 2013, 5:36:16 PM1/8/13
to publice...@googlegroups.com
Este codigo no me esta dando el resultado que yo quiero, que estare haciendo mal
 
Function UniqueID(tdDate)
Local lnSerie
    tdDate = Iif(Vartype(tdDate) == "T", tdDate, Datetime())
    lnSerie = 0
    lnSerie = lnSerie + Year(tdDate) * 10000
    lnSerie = lnSerie + Month(tdDate) * 1000
    lnSerie = lnSerie + Day(tdDate) * 100
    lnSerie = lnSerie + Hour(tdDate)
    lnSerie = lnSerie + Minute(tdDate)
    lnSerie = lnSerie + Sec(tdDate)
   * lnSerie = lnSerie + Seconds() * 0.1
Return (Round(lnSerie, 0))
 
Saludos

Víctor Hugo Espínola Domínguez

unread,
Jan 8, 2013, 6:11:34 PM1/8/13
to publicesvfoxpro
Hola ZeRoberto

Prueba esto:

Function UniqueID(tdDate)
Local lnSerie
    tdDate = Iif(Vartype(tdDate) == "T", tdDate, Datetime())
    lnSerie = 0
    lnSerie = lnSerie + Year(tdDate) * 10000000000
lnSerie = lnSerie + Month(tdDate) * 100000000
    lnSerie = lnSerie + Day(tdDate) * 1000000
    lnSerie = lnSerie + Hour(tdDate) * 10000
    lnSerie = lnSerie + Minute(tdDate) * 100
    lnSerie = lnSerie + Sec(tdDate)
   * lnSerie = lnSerie + Seconds() * 0.1
Return (Round(lnSerie, 0))

Ahí lo tienes hasta los segundos

Saludos,
Víctor.

Luis Maria Guayan

unread,
Jan 8, 2013, 7:10:50 PM1/8/13
to publice...@googlegroups.com
Victor la función que enviaste retorna lo mismo que esta sentencia

? TTOC(DATETIME(),1)

Luis María Guayán
Tucumán, Argentina
_________________________
http://www.PortalFox.com
Nada corre como un zorro
_________________________

El 08/01/2013 20:11, Víctor Hugo Espínola Domínguez escribió:
Function UniqueID(tdDate)
Local lnSerie
    tdDate = Iif(Vartype(tdDate) == "T", tdDate, Datetime())
    lnSerie = 0

Víctor Hugo Espínola Domínguez

unread,
Jan 8, 2013, 7:17:23 PM1/8/13
to publicesvfoxpro
Hola ZeRoberto

Hay un detalle que debes tener en cuenta: El número generado por tu función tiene 14 dígitos más la primera letra de la familia más marca, tienes un código muy largo ( los usuarios te odiarán y no tendrán buenos recuerdos de tu santa madre ) y existe la posibilidad  de que 2 usuarios diferentes obtengan el mismo número.
Te sugiero que tengas una tabla con dos campos: NombreTabla y UltimoNroGenerado, entonces tu función de UniqueId al ser llamada, bloquearia el registro de la tabla correspondiente, a continuación incrementa el campo UltimoNroGenerado y desbloquea el registro., este algoritmo nunca falla.
Si tienes alguna dificultad para escribir la función te podemos ayudar.

Saludos.
Víctor.



2013/1/8 Víctor Hugo Espínola Domínguez <vich...@gmail.com>

Víctor Hugo Espínola Domínguez

unread,
Jan 8, 2013, 7:32:55 PM1/8/13
to publicesvfoxpro
Hola Luís María

Es cierto, pero mi intención era seguir la lógica de ZeRoberto para que lo compare con su código, pues la consulta era:

>Este codigo no me esta dando el resultado que yo quiero, que estare haciendo mal

Hola ZeRoberto

Function UniqueId

Return VAL(TTOC(DATETIME(),1) + TRANSFORM(MOD(SECONDS(),1)*1000, "@L 999"))

Es la solución que te sugirió Luís María, una sola línea y 3 dígitos más que dificultaría un poco la repetición de la misma clave.

Saludos,
Víctor.



--
 
 

HernanCano

unread,
Jan 9, 2013, 9:18:29 AM1/9/13
to publice...@googlegroups.com
Roberto:

1.
Cuando posteaste las dos respueatas seguidas, ¿ya habías analizado la respuesta de Luis M.?

2.
¿De dónde sacaste esa función? Está mal implementada... al menos para el objetivo que pretendes.

3.
Si esa función tan rara hace algo tan similar a TTOC(,1), ¿de dónde salió?

HernanCano

unread,
Jan 9, 2013, 9:21:37 AM1/9/13
to publice...@googlegroups.com




Luis M. Guayán    
? TTOC(DATETIME(),1)

Víctor Hugo    
Return VAL(TTOC(DATETIME(),1) + TRANSFORM(MOD(SECONDS(),1)*1000, "@L 999"))

Muchachos: me les quito el sombrero...
Muchas gracias.




Víctor Hugo Espínola Domínguez

unread,
Jan 9, 2013, 9:32:37 AM1/9/13
to publicesvfoxpro
Hola Hernán

>Víctor Hugo     
>Return VAL(TTOC(DATETIME(),1) + TRANSFORM(MOD(SECONDS(),1)*1000, "@L 999"))

Ese código fue posteado por Luís María ;-)

Saludos.
Víctor.

Jose Ramon Veliz Martinez

unread,
Jan 9, 2013, 10:38:43 AM1/9/13
to publice...@googlegroups.com
Asi tomando en cuenta la hora y minutos y segundos

cFile=right(SYS(3),5)+TIME()
cfile=RIGHT(strt(abc,":",""),7)

Saludos

Juan Pop

unread,
Jan 9, 2013, 11:34:08 AM1/9/13
to publice...@googlegroups.com
Este es un aproximado de los milisegundos:

ALLTRIM(STR(ABS(INT(SECONDS())-SECONDS()),4,3))

ZeRoberto

unread,
Jan 9, 2013, 11:37:17 AM1/9/13
to publice...@googlegroups.com
Bueno ya desisti ir por ese camino, probe cambiandole las letras a numeros del SYS(2015) pero me da duplicados
 
Como funciona el SYS(2015) dice que en base al tiempo pero cuando le meto en un FOR..ENDFOR me repite el numero, checkenlo
 
Clear
For n = 1 to 20
    ? UniqueID(), Sys(2015)
EndFor
Return
 
Function UniqueID()
Local n, s, c
  s = SECONDS()
  n = (s / (60 * 60))
  c = Ttoc(Datetime(), 1) + Transform(Round(n * 10000, 0))
  ?? s, " "
Return (c)
 
Saludos
 


 

--
 
 

Luis Maria Guayan

unread,
Jan 9, 2013, 12:18:46 PM1/9/13
to publice...@googlegroups.com
Mira este artículo de PortalFox

--- SYS(2015) y su inversa ---
http://www.portalfox.com/article.php?sid=111



Luis María Guayán
Tucumán, Argentina
_________________________
http://www.PortalFox.com
Nada corre como un zorro
_________________________

--
 
 

Víctor Hugo Espínola Domínguez

unread,
Jan 9, 2013, 12:28:52 PM1/9/13
to publicesvfoxpro
Hola ZeRoberto

>pero cuando le meto en un FOR..ENDFOR me repite el numero

A eso me refería cuando te mencionaba que no hay garantía de obtener una clave única.

Mira y prueba este código:
Clear
For N = 1 To 20
? UniqueID(), Sys(2015)
Endfor
Return

Function UniqueID()

Return StrToLong( Substr( Sys(2015), 2 ) )

Function StrToLong
Lparameters lcLongstr
Local lnByte, lnRetval, lnLenStr, lnPosTmp, lcChrTmp

lnLenStr = Len( lcLongstr )
lnRetval = 0
For lnByte = 0 To lnLenStr - 1
lnPosTmp = lnLenStr - lnByte
lcChrTmp = Substr( lcLongstr, lnPosTmp, 1 )
lnRetval = lnRetval + ( Asc( lcChrTmp ) * ( 2^lnByte ) )
Next
Return lnRetval

Saludos.
Víctor
P.D.: Insisto en que la mejor solución es la función descrita en Portal Fox cuyo enlace te envió Luís María.

Luis Salazar

unread,
Jan 9, 2013, 12:50:36 PM1/9/13
to publice...@googlegroups.com
Bueno entiendo que estas refiriendote  a la fecha  NO al  DATEtimt();

convierte la fecha  a JULIANA y te da un numero unico

Digo yooo  ..  o cual es el fondo de la cosa ..
ya que no se si es un numero unico para el a#o  o que longitud de digitos requieres  ???

*+++++++++++++++++++++++++++++++++++++++++++++






--
 
 

Víctor Hugo Espínola Domínguez

unread,
Jan 9, 2013, 1:54:13 PM1/9/13
to publicesvfoxpro
Hola ZeRoberto

La mínima cantidad de dígitos que asegura la unicidad es 13 y te sirve solo para un siglo, prueba el siguiente código que usa la función B36ToB10 de Luís María :

Clear
For N = 1 To 20
? UniqueID(), Sys(2015)
Endfor
Return

Function UniqueID()
Local lnDias, lcAa, lcAaDdd

lnDias  = Date() - Date( Year( Date() ), 1, 1 ) + 1
lcAa    = Substr( Dtos( Date() ), 3, 2 )
lcAaDdd = lcAa + Transform( lnDias, "@L 999" )

Return lcAaDdd + Transform( B36ToB10( Substr( Sys(2015), 5 ) ), "@L 99999999" )

Function B36ToB10(tcN36)
Local lnN10, lcChr, lnLen, lnI, lnAux
tcN36 = Alltrim(Upper(tcN36))
lnLen = Len(tcN36)

lnN10 = 0
lnI = 1
For lnI = 1 To lnLen
lcChr = Subs(tcN36, lnI, 1)
lnAux = Asc(lcChr)-Iif(lcChr < 'A', 48, 55)
lnN10 = lnN10 + lnAux * 36^(lnLen-lnI)
Endfor
Return Int(lnN10)
Endfunc

Saludos.
Víctor.




El 9 de enero de 2013 12:37, ZeRoberto <zero...@gmail.com> escribió:
--
 
 

Dante

unread,
Jan 10, 2013, 8:58:27 AM1/10/13
to publice...@googlegroups.com
Como experiencia te comento que tuve que migrar de Motor de DB(a solicitud del cliente) algunos software con tablas que tenia como PK autoidentities en SQLSERVER y cuando se realizo eso grave error, se tenia que meter mano para evitar el rompimiento de las relaciones entre tablas, como tambien he tenido otros casos en el mismo motor.

Yo entiendo que los Autonumericos te facilitan la Vida, pero al final el mantenimiento o el seguimiento de los datos te conlleva a tomar decisiones equivocadas, tambien entiendo que Tu lo solucionas el problema que se puede presentar, pero te pregunto que pasaría si no te ubican o el cliente llama a otro especialista y ven un a o varias tablas y sorpresa lo encuentran asi:

Tabla
PK otros campos
1
2
3
5
6, etc


y se preguntaran y el PK 4?, Tu diras es que seguramente al grabar se cruzo con otra transaccion y se perdio el numero y ahora es el 5(porque el autoidenti trabaja asi), en cambio otros diran el registro fue borrado.El cliente a quien le cree, al que hizo el software o al que esta auditando los datos?

Los datos siempre deben ser consistentes, a parte de eso tambien puede existir otro campo que puede ser usado como indice unico, por ejemplo en un tabla producto.

PK, Código Único del negocio, descripcio,etc y quien se relacionas con las otras tablas es el campo PK y en el software el cliente vera su codigo que el personalizo a su manera.


Saludos y piénsenlo bien.

Miguel Antúnez

unread,
Jan 10, 2013, 10:12:53 AM1/10/13
to publice...@googlegroups.com
El que puedas rellenar códigos para que aparentemente no falta ningún registro, no quiere decir que se haya borrado. las suspicacias son similares, lo único que has hecho has escondido la evidencia. lo infalible no existe.     

La única forma de comprobar es guardando Log transaccionales, que te guarden siempre eventos por cada transacción que realices, aun mas con los errores que suceda, así puedes demostrar los cambios y errores.

El que hayas tenido una mala experiencia con los autoincrementales no le quita merito a su potencial y a  su facilidad de uso. En tu caso hubiera tenido en cuenta el comando 
"SET IDENTITY_INSERT [ database_name . [ schema_name ] . ] table { ON | OFF }"

el cual ten permite ingresar registros en el campo incremental, sobre todo para efectos de migración. 

Si quieres tener un código al cual el cliente esta acostumbrado es como poner un campo de descripción, con la característica de indice Único. 
Pero para que el cliente tendría que ver como esta relacionado sus tablas y que estas grabando en las tablas transaccionales, para eso se genera el aplicativo, para que el Usuario no necesite ver la Base de datos. 

Ademas que grabando códigos alfanuméricos le quitas performance a tu base de datos, es mucho mas ligero y rápido las relaciones con campos de tipo entero, que al final eso es lo que hace una relación buscar el el PK en un FK.

Ojala no suene  a que tenga la razón, solo es mi punto de vista y mi experiencia, es la forma que lo trabajo y lo veo, algunos estarán de acuerdo y algunos no, pero lo importante de compartir es ver puntos de vista  y experiencias distintos.

Saludos. 
 





      

Dante

unread,
Jan 10, 2013, 10:31:15 AM1/10/13
to publice...@googlegroups.com
Por lo que veo y comentas estas mencionando SQLSERVER como motor de datos y los comandos que comentas son ciertos, pero a modo de prueba migra tu data a otro motor (ORACLE,DB2) para que te saques dudas y te vas a dar cuenta que vas a meter mano y cambiar algunas cosas, cuando deberia ser transparente y no complicado de migrar de un lado a otro.

OJO No estoy diciendo que se use PK como tipo campos alfanumericos,caracter u otro porque eso es un grave error, simplemente el PK puede ser tipo Integer.

Con auditar me refiero a personas externas, que el cliente puede contratar para sacarse de dudas(es libre) y no que los usuarios del mismo cliente vean y manipulen los datos defrente en la BD.

Cierto son experiencias distintas y cada uno sacara sus propias concluciones. 

Saludos,

mpulla

unread,
Jan 10, 2013, 11:41:59 AM1/10/13
to publice...@googlegroups.com

Hola Dante.

Migrar de un db a otra, siempre será un problema, decir que debe ser transparente me suena que solo utilizas Sql standar, cada db tiene comandos que mejoran el perform y te hace la vida más fácil, aplicar estas características tiene un costo la migración.

Si contratan una auditoria, el profesional que va a hacer la auditoria debe tener el conocimiento del comportamiento de los auto numéricos.

Sql Server y Oracle tiene objetos sequence que tiene el mismo comportamiento de los auto numéricos, incrementan su valor cuando los solicitas independiente si se confirma o no la transacción, por lo que en algún momento vas a perder una secuencial, entonces el auditor mal puede pensar que los datos no son consistentes y si lo piensa que lo demuestre.

En todo caso les comento mi punto de vista.

Saludos
Mauricio

HernanCano

unread,
Jan 10, 2013, 2:47:44 PM1/10/13
to publice...@googlegroups.com

Hola.
Tengo una inquietud tanto para Dante como para mpulla.

Dante:
dice:

PK
1
2
3
5
6, etc
y se preguntarán y el PK 4? Tú dirás es que seguramente al grabar se cruzó con otra transacción y se perdió el número.

mpulla:
dice:

Sql Server y Oracle tiene objetos sequence que tiene el mismo comportamiento de los auto numéricos, incrementan su valor cuando los solicitas independiente si se confirma o no la transacción, por lo que en algún momento vas a perder una secuencial   ((¿se dice secuencia?))  (( el subrayado es mío ))

HCano pregunta:
¿Los campos autoincrementales incrementan (de todas formas) su consecutivo aunque el usuario pulse el botón Cancelar?

Tip:
En M$-SQL Server se dice IDENTITY.
En Access se dice Autonumérico (¡¡¡qué mal!!!).
En MySQL  se dice AUTO_INCREMENT.
En Oracle se dice SEQUENCE.
En PostgreSQL se dice SERIAL.
En VFP se dice AUTOINC.

¿Podríamos llamarlo AutoIncremental?

mpulla

unread,
Jan 10, 2013, 3:39:13 PM1/10/13
to publice...@googlegroups.com

Hola Hernan.

No tiene nada que ver con cancelar pues no has mandado nada al servidor para que actue con la tabla.

Los campos AutoIncrementales por lo general se los define como PK de la tabla y se los conoce como llaves artificiales, nunca deben ser usados como secuenciales de documentos porque su valor se incrementa independientemente se confirme o no la  transacción.

Se me ocurre este ejemplo espero sea claro...

Suponemos que tienes la tablas:
Ventas_cabeceta (AutoIncremental)
Ventas_Detalle ()
Item_Stock

Como regla no puede haber un item con stock < 0 y lo defines como regla en la tabla item_stock.

Haces una venta de un x Item con una cantidad mayor al stock actual,  al grabar corremos un sp

Begin Try
 Begin Transaction
   *-* valor actual del autoincremental para ventas_cabecera es de 30
    insert into Ventas_cabecera (....) values (.....)
    *OK el valor autoincremental se incremento 31

    Set @idVentasCabecera = SCOPE_IDENTITY()
    insert into Ventas_detalle (....) values (@idVentasCabecera.....)
    *OK

    update Item_Stock
     set nstock = nstock-30
    when iItemStockId = 1450
    *Error stock < 0
  Commit Transaction
End try

Begin Catch
 if @@TRANCOUNT > 0
    Rollback Transaction;
 Throw;
 end Catch

Si vuelves a corre el sp el valor del autoincremental para Ventas_cabecera sera de 31, es decir el valor 30 para la columna del autoincremntal se perdio por un error que se dio en la transacción

Saludos.
Mauricio

Dante

unread,
Jan 11, 2013, 8:58:40 AM1/11/13
to publice...@googlegroups.com
Estamos de acuerdo y muy claro el ejemplo.

ZeRoberto

unread,
Jan 14, 2013, 3:15:18 PM1/14/13
to publice...@googlegroups.com
que buena explicación maestro


--
 
 

ZeRoberto

unread,
Jan 14, 2013, 3:15:43 PM1/14/13
to publice...@googlegroups.com
Gracias Hugo voy a revisarlo.

Saludos

--
 
 

Reply all
Reply to author
Forward
0 new messages