疯狂的问题。我知道。这是一个场景:
我的客户有几个ColdFusion网站,它们都在同一个iSeries数据库上访问同一个库。比方说,为了论证起见,以下SQL查询可以从以下任何网站运行:
<cfquery datasource="myDS">
INSERT INTO XQX.myTable
(
x_ID,
x_Name,
x_Phone
)
VALUES
(
#myId#,
#Name#,
#Phone#
)
</cfquery>
(我知道没有CFQUERYPARAM等,为了简单起见,我们假设上面的查询是A-Ok)
我可以通过在插入之前查询表来获得最大值,然后递增它来生成Id,如下所示:
<cfquery name="qMaxId" datasource="myDS">
SELECT MAX(x_Id) AS MaxId
FROM XQX.myTable
</cfquery>
<cfset myId = qMaxId.MaxId + 1 />
但是,我担心两个用户在相同的确切时间打表,并且都得到相同的"新"Id。
有什么想法吗?
特别是在web环境中,应该担心并发用户。尝试像这样用MAX()
生成id有两个固有的问题:
- 您不"同步"访问,两个用户最终会使用相同的id
- 您执行"同步"访问,并为表插入创建了瓶颈
DB2(通常是iSeries上的标准配置)有一个名为SEQUENCE的东西,您可以查询它来生成ID
我对冷融合一无所知,但有这样的东西:
<cfquery name="qNextId" datasource="myDS">
SELECT NEXTVAL FOR [sequencename] AS NextId
FROM Sysibm.Sysdummy1
</cfquery>
<cfset myId = qNextId.NextId />
除了@X-Zero指出的SEQUENCE之外,IBM DB2管理员还可以在数据库中放入一个名为IDENTITY的自动递增列。
create MYTABLE ...
(ID int
generated always as IDENTITY(Start with 1
Increment by 1)
...
您可以使用Sequence对象。例如
CREATE SEQUENCE XQX.mySeqObj
as {numeric-datatype}
数据类型可以是SMALLINT、INTEGER、BIGINT、DECIMAL或NUMERIC,小数位数为零(即没有小数位数)。将创建一个数据区域来存储该值。
然后,您可以使用NEXT VALUE FOR
表达式来检索和递增序列,如中所示
INSERT INTO XQX.myTable
(
x_ID,
x_Name,
x_Phone
)
VALUES
(
NEXT VALUE FOR XQX.mySeqObj,
#Name#,
#Phone#
)
如果希望知道在当前会话中指定的先前值,则可以使用表达式PREVIOUS VALUE FOR mySeqObj
,但当然,只有在会话中使用了NEXT VALUE
表达式之后。