11 de septiembre de 2002

Campos "Autoincrementales" en VFP (anteriores a la versión 8)

Ejemplo de como podemos implementar campos autoincrementales en nuestras tablas de Visual FoxPro® contenidas en una Base de Datos.
Nota: Esto es para versiones anteriores a VFP8, ya que esta versión ya posee nativamente la característica de campos autoincrementales en sus tablas.
Para lograr esto seguimos los siguientes pasos:
  • Creamos una Base de Datos de ejemplo: "EjemploDBC.DBC"
  • Creamos dos Tablas de ejemplo: "Ejemplo1.DBF" y "Ejemplo2.DBF"
  • Creamos una Tabla que almacenará los valores Id's Autoincremetales de cada tabla que lo necesite. Esta tendrá un registro por tabla: "Tabla_Ids.DBF"
  • Creamos un Procedimiento Almacenado: "NuevoId(tcAlias)"

El siguiente código crea la DBC y DBF's.

CREATE DATABASE EjemploDBC
SET DATABASE TO EjemploDBC

*-- Tabla de Ejemplo
CREATE TABLE Ejemplo1 ;
  (uId I NOT NULL DEFAULT NuevoId("Ejemplo1"), ;
  cCampo C(10) NOT NULL)

*-- Tabla de Ejemplo
CREATE TABLE Ejemplo2 ;
  (uId I NOT NULL DEFAULT NuevoId("Ejemplo2"), ;
  nCampo N(10,2) NOT NULL)

*-- Tabla con los nombres de tablas y sus Id's
CREATE TABLE Tabla_Ids ;
  (NombreTabla C(30) NOT NULL, ;
  uId I NOT NULL)
INDEX ON UPPER(NombreTabla) TAG NomTab

*-- Por cada tabla que requiera un campo
*   Id Autoincremental añado un registro
INSERT INTO Tabla_Ids VALUES("Ejemplo1", 0)
INSERT INTO Tabla_Ids VALUES("Ejemplo2", 0)

CLOSE DATABASES
RETURN

Para crear el Procedimiento Almacenado, modificamos la Base de Datos "EjemploDBC.DBC" con:
MODIFY DATABASE EjemploDBC
y en la ventana de Procedimientos Almacenados (Menú -> Base de datos -> Modificar procedimientos almacenados) copiamos la siguiente función:

FUNCTION NuevoID(tcAlias)
  LOCAL lcAlias, lnID, lnAreaAnt, lcReprAnt
  lnID = 0
  lnAreaAnt = SELECT()
  lcReprAnt = SET('REPROCESS')
  SET REPROCESS TO AUTOMATIC
  lcAlias = UPPER(ALLTRIM(tcAlias))
  IF NOT USED("Tabla_Ids")
    USE EjemploDBC!Tabla_Ids IN 0
  ENDIF
  SELECT Tabla_Ids
  IF SEEK(lcAlias, "Tabla_Ids", "NomTab")
    IF RLOCK()
      REPLACE uId WITH Tabla_Ids.uId + 1 IN Tabla_Ids
      lnID = Tabla_Ids.uId
      UNLOCK
    ENDIF
  ENDIF
  SELECT (lnAreaAnt)
  SET REPROCESS TO lcReprAnt
  RETURN lnID
ENDFUNC

Las tablas "Ejemplo1.DBF" y "Ejemplo2.DBF" contienen el campo uId que automaticamente se incrementa por el Procedimiento Almacenado cada vez que hacemos un INSERT.

Ahora miremos el ejemplo de como funcionan:

IF NOT USED("Ejemplo1")
  USE Ejemplo1 IN 0
ENDIF 
IF NOT USED("Ejemplo2")
  USE Ejemplo2 IN 0
ENDIF 
FOR ln = 1 TO 100
  INSERT INTO Ejemplo1 (cCampo) ;
    VALUES(SYS(2015))
  INSERT INTO Ejemplo2 (nCampo) ;
    VALUES(RAND()*1000)
ENDF

Note que no se incluye el campo uId en la lista de los campos. El campo uId contine un valor por defecto. Este valor por defecto es realmente una llamada al procedimiento almacenado (NuevoId()) que retorna un número único que se agrega al campo uId de la tabla pasada como parámetro cuando añadimos un nuevo registro.
Nota: Parte del código de este artículo fue tomado y ligeramente modificado del artículo de la MSKB http://support.microsoft.com/kb/316910/es

No hay comentarios. :

Publicar un comentario