所以主程序在C#中。将新记录插入VFP数据库表。通过
生成记录的下一个ID需要很长时间select max(id)+1 from table
,所以我将该代码放入VFP中的编译dll中,并通过C#调用该COM对象。
COM对象在大约250ms内返回新ID。然后,我只是通过OLEDB进行更新。我遇到的问题是,在COM对象返回新插入的ID之后,我无法通过OLEDB立即从C#中找到它
select id form table where id = *newlyReturnedID*
返回0行。如果我等待一段未知时间,查询将返回1行。我只能假设它立即返回0行,因为它尚未将新的ID添加到索引中,因此select无法找到它。
有没有其他人遇到过类似的事情?如果是这样,你是如何处理它的?
DD
答案 0 :(得分:4)
警告:您的代码在多用户环境中存在缺陷。两个人可以同时运行查询并获得相同的ID。如果列具有主键或候选键,则其中一个将在INSERT上失败,这是关键字段的最佳实践。
我的建议是让ID成为自动递增的整数字段(我不是它们的粉丝),或者甚至更好,创建一个键表。表中的每条记录都是针对获取密钥的表。我使用类似于此的结构:
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()
如果参数()< 1 lcAlias = ALIAS()
如果CURSORGETPROP(“SOURCETYPE”)= DB_SRCLOCALVIEW * - 尝试获取基表 lcAlias = LOWER(CURSORGETPROP(“TABLES”)) lcAlias = SUBSTR(lcAlias,AT(“!”,lcAlias)+ 1) 万一 其他 lcAlias = LOWER(tcAlias) ENDIF
lnOrderNumber = 0 lnOldReprocess = SET('REPROCESS')
* - 锁定直到用户按下Esc SET REPROCESS TO AUTOMATIC
IF!USED(“countergenerator”) 使用EventManagement!countergenerator IN 0 SHARED ALIAS countergenerator ENDIF
SELECT countergenerator
如果寻求(LOWER(lcAlias),“countergenerator”,“ckey”) 如果RLOCK() lnNextValue = countergenerator.iValue 使用countergenerator.iValue + 1替换countergenerator.iValue 开锁 万一 其他 *使用起始值创建新记录。 APPEND BLANK IN countergenerator SCATTER MEMVAR备忘录 m.cKey = LOWER(lcAlias) m.iValue = 1 m.mNote =“由存储过程自动创建。” m.tUpdated = DATETIME() 收集MEMVAR备忘录
如果RLOCK() lnNextValue = countergenerator.iValue 使用countergenerator.iValue + 1替换countergenerator.iValue 开锁 万一 ENDIF
SELECT(lnOldArea) 设置对lnOldReprocess的重现
RETURN lnNextValue ENDFUNC
RLOCK()确保不存在对记录的争用,并且足够快以至于没有瓶颈过程。这比你目前采用的方法更安全。
Rick Schummer VFP MVP答案 1 :(得分:0)
VFP需要FLUSH其工作区。