VFP inserción, actualización del índice
-
12-09-2019 - |
Pregunta
De modo que el principal programa en C#.La inserción de nuevos registros en una tabla de base de datos de VFP.Se estaba tomando demasiado tiempo para generar el siguiente IDENTIFICADOR para el registro a través de
select max(id)+1 from table
, por lo que poner ese código en una compilación de dll en VFP y estoy llamando a ese objeto COM a través de C#.
El objeto COM devuelve el ID nuevo en alrededor de 250 ms.A continuación, sólo hacer una actualización a través de OLEDB.El problema que estoy teniendo es que después de que el objeto COM devuelve el recién ID insertado, no puedo encontrar inmediatamente desde C# a través de la OLEDB
select id form table where id = *newlyReturnedID*
devuelve 0 filas de atrás.Si tengo que esperar un tiempo desconocido período de la consulta devolverá 1 fila.Sólo puedo suponer que se devuelve 0 filas inmediatamente porque aún no se ha añadir la de nuevo cuño de IDENTIFICACIÓN en el índice y por lo tanto el select no se puede encontrar.
Tiene alguien alguna vez algo similar?Si es así, ¿cómo manejarlo?
DD
Solución
Advertencia:el código es erróneo, en un entorno multi-usuario.Dos personas se pudo ejecutar la consulta en el mismo tiempo y obtener el mismo ID.Uno de ellos se producirá un error en la INSERCIÓN si la columna tiene un principal o clave candidata, que es una de las mejores prácticas para los campos de clave.
Mi recomendación es tener el IDENTIFICADOR de ser un auto-incrementar campo entero (yo no soy un fan de ellos), o mejor aún, crear una tabla de claves.Cada registro de la tabla es una tabla que presenta las claves asignadas.Yo uso el de una estructura similar a esta:
Structure for: countergenerator.dbf Database Name: conferencereg.dbc Long table name: countergenerator Number of records: 0 Last updated: 11/08/2008 Memo file block size: 64 Code Page: 1252 Table Type: Visual FoxPro Table Field Name Type Size Nulls Next Step Default ---------------------------------------------------------------------------------------------------------------- 1 ccountergenerator_pk Character 36 N guid(36) 2 ckey Character (Binary) 50 Y 3 ivalue Integer 4 Y 4 mnote Memo 4 Y "Automatically created" 5 cuserid Character 30 Y 6 tupdated DateTime 8 Y DATETIME() Index Tags: 1. Tag Name: PRIMARY - Type: primary - Key Expression: ccountergenerator_pk - Filter: (nothing) - Order: ascending - Collate Sequence: machine 2. Tag Name: CKEY - Type: regular - Key Expression: lower(ckey) - Filter: (nothing) - Order: ascending - Collate Sequence: machine
Ahora el código para el procedimiento almacenado en el DBC (o en otro programa) es este:
FUNCIÓN NextCounter(tcAlias)
LOCAL lcAlias, ;lnNextValue, ;lnOldReprocess, ;lnOldArea
lnOldArea = SELECCIONAR()
SI LOS PARÁMETROS() <1 lcAlias = ALIAS()
SI CURSORGETPROP("SOURCETYPE") = DB_SRCLOCALVIEW *-- Intento de obtener la tabla de base de lcAlias = MENOR(CURSORGETPROP("TABLAS")) lcAlias = SUBSTR(lcAlias, EN("!", lcAlias) + 1) ENDIF Otra COSA lcAlias = MENOR(tcAlias) ENDIF
lnOrderNumber = 0 lnOldReprocess = SET('volver a procesar')
*-- Bloqueo hasta que el usuario pulsa Esc SET REPROCESS AUTOMÁTICO
SI!!!Se UTILIZAN("countergenerator") USO EventManagement!countergenerator EN 0 COMPARTIDA ALIAS countergenerator ENDIF
SELECCIONE countergenerator
SI BUSCAN(INFERIOR(lcAlias), "countergenerator", "ckey") SI RLOCK() lnNextValue = countergenerator.iValue REEMPLAZAR countergenerator.iValue CON countergenerator.iValue + 1 DESBLOQUEAR ENDIF Otra COSA * Crear el nuevo registro con el valor inicial.ANEXAR en BLANCO EN countergenerator SCATTER MEMVAR MEMO m.cKey = MENOR(lcAlias) m.iValue = 1 m.mNote = "creado Automáticamente por el procedimiento almacenado." m.tUpdated = DATETIME() SE REÚNEN MEMVAR MEMO
SI RLOCK() lnNextValue = countergenerator.iValue REEMPLAZAR countergenerator.iValue CON countergenerator.iValue + 1 DESBLOQUEAR ENDIF ENDIF
SELECCIONE (lnOldArea) CONJUNTO de volver a procesar A lnOldReprocess
VOLVER lnNextValue ENDFUNC
El RLOCK() se asegura de que no hay disputas por los registros y es lo suficientemente rápido como para no tener cuello de botella en el proceso.Esta es la forma más segura que el enfoque que está tomando actualmente.
Rick Schummer
VFP MVP
Otros consejos
FLUSH sus áreas de trabajo .