Asp classic 传统Visual Fox Pro应用程序中的非自动递增主键
首先让我说我根本不能修改数据库模式 我无法访问任何与数据库交互的现有代码。这是一个已编译的程序集,我无法反编译 我有一个数据库表,其值在代码中逻辑上作为主键,但不是自动递增的 现在是转折点,有时按键递增正数,有时递增负数: 找不到hilo代码的任何证据Asp classic 传统Visual Fox Pro应用程序中的非自动递增主键,asp-classic,visual-foxpro,dbase,Asp Classic,Visual Foxpro,Dbase,首先让我说我根本不能修改数据库模式 我无法访问任何与数据库交互的现有代码。这是一个已编译的程序集,我无法反编译 我有一个数据库表,其值在代码中逻辑上作为主键,但不是自动递增的 现在是转折点,有时按键递增正数,有时递增负数: 找不到hilo代码的任何证据 我不知道如何处理这个问题,除了选择Top1,添加一个值,希望不会出现重叠 不知道你需要什么,但是如果你需要额外的PK,你可以使用记录号码: SELECT RECNO() FROM table1 如果您的表是数据库容器*.DBC的一部分,而不是空
我不知道如何处理这个问题,除了选择Top1,添加一个值,希望不会出现重叠 不知道你需要什么,但是如果你需要额外的PK,你可以使用记录号码:
SELECT RECNO() FROM table1
如果您的表是数据库容器*.DBC的一部分,而不是空闲表,那么您可能会在数据库容器中找到自动递增键的代码 如果打开表格并使用“修改结构”命令,则可以在第三个选项卡上看到表格的属性。如果表是数据库容器的成员,则将显示数据库的名称,以及包括触发器和记录规则在内的任何规则,这些规则在每次写入表时都会执行 在添加自动递增字段之前的几天,我通过添加记录规则实现了自动递增字段,如下所示:
PROCEDURE TABLE_RR
LOCAL nOldArea,nUnique
IF PK=0 &&Only update primary key field when not already set
STORE SELECT() TO nOldArea
&&Open table again in another work area, we can't move the record pointer in a Rule
IF !USED("TABLE_RR")
USE TABLE.DBF IN 0 NOUPDATE AGAIN ALIAS TABLE_RR
ENDIF
&&Find current maximum value of primary key field, add 1 as next primary key field
SELECT TABLE_RR
SET ORDER TO PKTable
GO BOTT
STORE 1+PK TO nUnique
&&Update primary key field for our record
SELECT(nOldArea)
REPLACE PK WITH nUnique
ENDIF
&&Record rule must return true or changes are rejected
RETURN .T.
ENDPROC
将此类规则存储在数据库容器存储过程代码区域是正常的习惯和做法,但是,如果正在运行的应用程序能够找到函数,它将执行。显然,上面的代码示例假定该表名为table,有一个名为PK的数字Int字段,该字段的索引标记为PKTable
因为代码在记录规则中,所以在任何更新期间它都会在记录上执行,因此记录被锁定时,不会发生冲突。任何在PK中没有值的记录都会得到该字段当前最高值的1+。记录规则用于验证记录并拒绝无效值,并且必须返回true.T。为了让这封信被接受。过程中可能会出现其他代码,包括将当前值设置为时间戳字段等
记录规则可通过ALTER table命令应用于表格:
ALTER TABLE 'TABLENAME' SET CHECK PROCEDURENAME()
或者通过MODIFY STRUCTURE中的交互式表编辑器尽管Steve的解决方案非常好,特别是利用数据库容器和分配规则,但显然您对自己的情况有些困惑。如果您试图添加记录,并且需要创建自己的自动增量,那么您可能只需通过过程调用并分配它即可。这只是一个例子,但可能对您有所帮助
FUNCTION AddMyNewRecord()
*/ localized variable so you don't accidentally mangle some otherwise
*/ coincidental variable somewhere else. Preserve work area at start
local lnSelect, llSaveOk, lnAttempts, lnNewPKID
lnSelect = select()
llSaveOk = .f.
select YourAddressTable
if NOT FLOCK()
lnAttempts = 0
do while lnAttempts < 10 AND NOT FLOCK()
wait window "Attempting lock for address table..." timeout 1
enddo
endif
if NOT FLOCK()
messagebox( "Unable to lock file to add next record primary key." )
else
*/ We have a lock, now try to detect both the highest and lowest
*/ EXISTING key for the table
use in select( "C_TryNextKey" )
select MIN( YAT.PK ) as MinKey,;
MAX( YAT.PK ) as MaxKey ;
from ;
YourAddressTable YAT;
into ;
cursor C_TryNextKey readwrite
*/ Determine if you need higher or lower key sequence
if CriteriaForPositiveKey
lnNewPKID = C_TryNextKey.MaxKey +1
else
*/ must be getting next LOWER sequence
lnNewPKID = C_TryNextKey.MinKey -1
endif
*/ close temp cursor from getting respective high / low key
use in select( "C_TryNextKey" )
*/ NOW, we can add the new record
Select YourAddressTable
APPEND BLANK
*/ replace PK and all the other fields you need to do too
Replace PK with lnNewPKID,;
Address1 with lcSomeVariableYouHaveForAddress1,;
Address2 with lcSomeVariableForAddress2,;
AnyOtherFields with lcOtherFieldsToBeSet
*/ Unlock the address table
UNLOCK
*/ set flag so we know it worked vs not.
llSaveOk = .t.
endif
*/ Return back where it started
select( lnSelect )
*/ Return if the save was ok or not.
return llSaveOk
endproc
这不会修改现有的数据库或表结构。但是,在插入新记录内容之前,它会尝试锁定表。然后看看最低和最高的ID。你必须分析数据,找出为什么有些ID是负值和正值,并更新我在上面代码中输入的条件。最后,打开桌子
如果这样做有意义,很好,如果您需要调整,请告诉我,我会尽力为您提供更多指导。我将如何插入该值?首先让我说,我根本无法修改数据库架构。'不过,感谢您给出完整的答案:首先让我说我根本无法修改数据库模式。