Codigo autogenerado

635 views
Skip to first unread message

Juan Morales

unread,
Mar 22, 2013, 7:59:02 AM3/22/13
to publice...@googlegroups.com
buenos días,
 
tengo un problema que me sucede de vez en cuando, tengo una tabla en la cual distintos usuarios registran movimientos el código de esta operación se autogenera y es algo asi C03-0001, lo que me sucede es que a veces este código se me repite y no se como controlarlo, al estar varios usuarios ingresando movimientos en forma simultanea a veces estos códigos se repiten y no se como controlarlo.
 
tengo una tabla en la cual almaceno el ultimo numero cada vez que un usuario graba buscar este ultimo numero, le suma uno y lo graba, existe una mejor forma de hacerlo.
 
ojo el código depende de tipo de Empresa  y periodo se podrían repetir solo en estos caso
 
IdEmpresa       Periodo         Codigo
      1                 2013/01       C01-0001
      2                 2013/01       C01-0001
      1                 2012/01       C01-0001  
 
 

Carlos Miguel FARIAS

unread,
Mar 22, 2013, 8:29:07 AM3/22/13
to publice...@googlegroups.com
Cuando lees la tabla de códigos (últimos) como determinas cual lees? Porque veo que id empresa se repite y lo mismo periodo.
Tienes una clave primaria para la combinación empresa-periodo?
Al acceder al registro de la tabla de códigos, ubicas el registro e intentas LOCKearlo? o sea impedir que otros usuarios lo accedan mientras lo incrementas antes de guardarlo y UNLOCKearlo después?
Saludos: Miguel, La Pampa (RA)
Message has been deleted

Miguel Antúnez

unread,
Mar 22, 2013, 8:35:29 AM3/22/13
to publice...@googlegroups.com
Si esta trabajando con DBF's, al campo considerarlo como clave "candidate", así evitaras registros duplicados, al momento de grabar controla el error generando un nuevo correlativo. 

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

Juan Morales

unread,
Mar 22, 2013, 8:57:08 AM3/22/13
to publice...@googlegroups.com
Trabajo con Tablas en SQL Server 2008
Message has been deleted

Luis Maria Guayan

unread,
Mar 22, 2013, 8:54:52 AM3/22/13
to publice...@googlegroups.com
Mira si esto se ajusta a tus necesidades

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


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

Juan Morales

unread,
Mar 22, 2013, 9:07:53 AM3/22/13
to publice...@googlegroups.com
gracias por el articulo si lo había leído, mi pregunta es se pueden bloquear registros en tablas SQL Server

Miguel Antúnez

unread,
Mar 22, 2013, 9:08:02 AM3/22/13
to publice...@googlegroups.com
En SQLServer hay una condición similar, que son los indices UNIQUE, este indice evitara que hayan registros duplicados. 
En mi caso prefiero llevar una tabla de correlativos por separado con la siguiente idea

begin transaction
 set @ncorr=(select max(campocorr)+1 from tablacorrelativos)
 insert into tdocumn  values (@ncorr,etccampos.....)
 update tablacorrelativos set campocorr=@ncorr
commit transacction

las transacciones automáticamente bloquean los registros y evitan duplicidad de registros, 

Saludos. 


Juan Morales

unread,
Mar 22, 2013, 9:10:34 AM3/22/13
to publice...@googlegroups.com
podrias explicarme un poco mas por favor y si te es posible con un ejemplo, recién estoy trabajando con sql server
 
gracias por tu tiempo

smartito

unread,
Mar 22, 2013, 11:05:09 AM3/22/13
to publice...@googlegroups.com
dado que esta funcion es para dbf, me vi en la necesidad de modificarla para cualquier bd en mi caso es SQlserver, utilizando ADO, la estructura al inicio es la misma lo que cambia en si es la funcion.

FUNCTION NuevoID(tcAlias)
#INCLUDE ADOVFP.H
LOCAL cn,rs,Msql,lnID

cn=CreateObject("adodb.connection")
rs=CreateObject("adodb.recordset")
cn.ConnectionString="Provider=SQLOLEDB.1;Data Source=TUSERVER;Initial Catalog=TUBD;Integrated Security=SSPI;"
cn.open()

msql="select * from IDS WHERE Ctabla='"+tcAlias+"'"

rs.Open(mSql, cn,adOpenKeyset,adLockOptimistic,adCmdText)

IF NOT rs.eof()
lnID = rs.Fields(1).Value + 1
rs.Fields(1).value = lnID
rs.Update()
ENDIF
rs.close()
RETURN lnID
ENDFUNC


Archivo AdoVfp.h

*--------------------------------------------------------------------
* Microsoft ADO
*
* (c) 1998 Microsoft Corporation. All Rights Reserved.
*
*
*
* ADO constants include file for Visual FoxPro
*
*--------------------------------------------------------------------

*---- CursorTypeEnum Values ----
#DEFINE ADOPENFORWARDONLY 0
#DEFINE ADOPENKEYSET 1
#DEFINE ADOPENDYNAMIC 2
#DEFINE ADOPENSTATIC 3

*---- CursorOptionEnum Values ----
#DEFINE ADHOLDRECORDS 0x00000100
#DEFINE ADMOVEPREVIOUS 0x00000200
#DEFINE ADADDNEW 0x01000400
#DEFINE ADDELETE 0x01000800
#DEFINE ADUPDATE 0x01008000
#DEFINE ADBOOKMARK 0x00002000
#DEFINE ADAPPROXPOSITION 0x00004000
#DEFINE ADUPDATEBATCH 0x00010000
#DEFINE ADRESYNC 0x00020000
#DEFINE ADNOTIFY 0x00040000

*---- LockTypeEnum Values ----
#DEFINE ADLOCKREADONLY 1
#DEFINE ADLOCKPESSIMI

Es una respuesta al articulo publicado por Luis Maria Guayan... en vez de con DBFs con SQL mediante ADO. Espero que pueda servirte.

Saludos,

Miguel Antúnez

unread,
Mar 22, 2013, 11:52:16 AM3/22/13
to publice...@googlegroups.com
Hola Juan, te envio un pequeño ejemplo.
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[tcorr](
[id_corr] [int] IDENTITY(1,1) NOT NULL,
[ncorrbol] [int] NULL,
[ncorrfc] [int] NULL,
 CONSTRAINT [PK_tcorr] PRIMARY KEY CLUSTERED 
(
[id_corr] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
USE [ejemplos]
GO

/****** Object:  Table [dbo].[tdoc]    Script Date: 22/03/2013 10:45:15 a.m. ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[tdoc](
[id_doc] [int] IDENTITY(1,1) NOT NULL,
[ndoc] [char](10) NULL,
[c3] [char](10) NULL,
[c4] [datetime] NULL,
 CONSTRAINT [PK_tdoc] PRIMARY KEY CLUSTERED 
(
[id_doc] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
USE [ejemplos]
GO

/****** Object:  Index [IX_tdoc]    Script Date: 22/03/2013 10:45:46 a.m. ******/
CREATE UNIQUE NONCLUSTERED INDEX [IX_tdoc] ON [dbo].[tdoc]
(
[ndoc] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
go
select * from [dbo].[tcorr]
go
select * from [dbo].[tdoc]
go
insert into tcorr values (0,0)
go
create procedure ingre_doc
@id_doc int output,
@ndoc char(10) output,
@c3 char(10),
@c4 datetime
as
begin try
begin transaction 
set @ndoc=(select max(ncorrbol)+1 from tcorr where id_corr=1 )
update tcorr set ncorrbol=ncorrbol+1 where id_corr=1 
insert into tdoc values (@ndoc,@c3,@c4)
set @id_doc=@@IDENTITY
commit transaction
end try
begin catch
rollback transaction
end catch
go
---Probando
execute ingre_doc 0,'','test1','20130101'

Saludos.

mpulla

unread,
Mar 22, 2013, 11:53:44 AM3/22/13
to publice...@googlegroups.com

Hola Juan

Si estas comenzando con sql server te recomendaría que utilices Sql server 2012, tiene muchas funciones nuevas.

Por lo del secuencial al igual que Miguel y Smartito, tengo una tabla de secuencias, es mucho mejor y te va evitar problemas de bloqueos.
Te envió 2 sp que hacen lo mismo, el segundo sp usa merger que según dice MS tiene un mejor desempeño

Saludos.
Mauricio

ALTER PROCEDURE [App].[SeveralSecManager_spUI] @tiYear int, @tiIdKey int, @tcDescripcion Char(60), @iKeyNext INT OUTPUT
AS
SET NOCOUNT ON
Begin Try
UPDATE App.SeveralSec SET @iKeyNext = iSecuencia =iSecuencia + 1 Where iYear = @tiYear And iSecId = @tiIdKey
IF @@ROWCOUNT = 0
   Begin
     Insert Into App.SeveralSec (iSecId, iYear, cDescripcion, iSecuencia) Values(@tiIdKey, @tiYear, @tcDescripcion, 1)
     Set @iKeyNext = 1
   end
end Try

Begin Catch
    Throw;
end catch


ALTER PROCEDURE [App].[SecuenciaSimpleSec_spUI] @iKey int, @cDescripcion nVarChar(50) = NULL, @iKeyNext INT OUTPUT
AS
SET NOCOUNT ON

Begin Try

 DECLARE @R TABLE (
 iSecId int NOT NULL PRIMARY KEY,
 iSecuencia INT NOT NULL CHECK (iSecuencia > 0)
 );

INSERT INTO @R (iSecId, iSecuencia)
SELECT
    z.iSecId, z.iSecuencia
FROM
    (
    MERGE App.SecuenciaSimple WITH (HOLDLOCK) AS T
    USING (SELECT @iKey, @cDescripcion) AS S (iKey, cDescripcion)
    ON T.iSecId = S.iKey
    WHEN MATCHED THEN
        UPDATE SET iSecuencia = iSecuencia + 1
    WHEN NOT MATCHED THEN   
        INSERT (iSecId, cDescripcion, iSecuencia)
        VALUES (S.iKey, S.cDescripcion, 1)
    OUTPUT
        $ACTION AS [action], INSERTED.iSecId, INSERTED.iSecuencia
    ) AS z;


SELECT @iKeyNext = iSecuencia FROM @R WHERE iSecId = @iKey;

End try

Begin Catch
    Throw;
end catch

Reply all
Reply to author
Forward
0 new messages