2009-07-10 3 views
0

Итак, основная программа находится в C#. Вставка новых записей в таблицу базы данных VFP. Это занимает слишком много времени, чтобы создать следующий идентификатор для записи с помощьюВставка VFP, обновление индекса

select max(id)+1 from table 

, поэтому я ставлю этот код в компиляции DLL в VFP и звонит, что COM-объект через C#.

COM-объект возвращает новый идентификатор примерно в 250 мс. Затем я просто делаю обновление через OLEDB. Проблема, которую я имею, что после того, как объект COM возвращает вновь вставленный ID, я не могу сразу найти его из C# через OLEDB

select id form table where id = *newlyReturnedID* 

возвращает 0 строк назад. Если я подождаю неизвестный период времени, запрос вернет 1 строку. Я могу только предположить, что он сразу возвращает 0 строк, потому что он еще не добавил новый чеканированный идентификатор в индекс, и поэтому выбор не может его найти.

Неужели кто-нибудь еще сталкивается с чем-то подобным? Если да, то как вы справились с этим?

DD

ответ

4

Предупреждение: ваш код испорчен в многопользовательской среде. Два человека могут одновременно запускать запрос и получать одинаковый идентификатор. Один из них потерпит неудачу в INSERT, если в столбце есть первичный или кандидатный ключ, что является лучшей практикой для ключевых полей.

Моя рекомендация состоит в том, чтобы иметь идентификатор, являющийся автоматически увеличивающимся целым полем (я не являюсь их фанатом), или даже лучше создать таблицу ключей. Каждая запись в таблице предназначена для таблицы, которая получает назначенные ключи. Я использую структуру, аналогичную этой:

 
     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 

Теперь код для хранимой процедуры в DBC (или в другой программе) заключается в следующем:

ФУНКЦИЯ NextCounter (tcAlias)

LOCAL lcAlias,; lnNextValue,; lnOldReprocess;; lnOldArea

lnOldArea = SELECT()

IF ПАРАМЕТРАМИ() lcAlias ​​= ALIAS()

IF CURSORGETPROP ("SourceType") = DB_SRCLOCALVIEW * - Попытка получить базовую таблицу lcAlias ​​= LOWER (CURSORGETPROP ("ТАБЛИЦЫ")) lcAlias ​​= SUBSTR (lcAlias, AT ("!", lcAlias) + 1) ENDIF ELSE lcAlias ​​= LOWER (tcAlias) ENDIF

lnOrderNumber = 0 lnOldReprocess = SET ('Обработать')

* - блокировка до пользователь нажимает Esc SET Reprocess TO AUTOMATIC

если используется ("countergenerator") USE EventManagement!В countergenerator 0 ШАРЕД ALIAS countergenerator ENDIF

ВЫБОР countergenerator

ЕСЛИ SEEK (ниже (lcAlias), "countergenerator", "CKEY") ЕСЛИ RLOCK() lnNextValue = countergenerator.iValue ЗАМЕНЫ countergenerator.iValue WITH countergenerator.iValue + 1 UNLOCK ENDIF ELSE * Создайте новую запись со стартовым значением. APPEND BLANK В countergenerator SCATTER MEMVAR MEMO m.cKey = НИЖНИЙ (lcAlias) m.iValue = 1 m.mNote = "Автоматически созданный хранимая процедура." m.tUpdated = DATETIME() GATHER MEMVAR Memo

ЕСЛИ RLOCK() lnNextValue = countergenerator.iValue ЗАМЕНЫ countergenerator.iValue С countergenerator.iValue + 1 ОТПЕРЕТЬ ENDIF ENDIF

SELECT (lnOldArea) SET TO Reprocess lnOldReprocess

RETURN lnNextValue EndFunc

RLOCK() гарантирует, что для записей нет конкуренции, и он достаточно быстр, чтобы не иметь узкого места в процессе. Это намного безопаснее, чем подход, который вы сейчас используете.

Рик Schummer
VFP MVP

Смежные вопросы