2

疯狂的问题。我知道。这是场景:

我的客户有几个 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。

有什么想法吗?

4

3 回答 3

3

除了@X-Zero 提到的 SEQUENCE 之外,IBM DB2 管理员还可以在数据库中放置一个称为 IDENTITY 的自动递增列。

create MYTABLE ...
(ID int 
    generated always as IDENTITY(Start with 1 
                                 Increment by 1)
... 
于 2012-03-06T18:58:55.533 回答
3

尤其是在 Web 环境中,您应该担心并发用户。尝试像这样生成 id 存在两个固有问题MAX()

  1. 您没有“同步”访问,两个用户最终使用相同的 ID。
  2. 进行“同步”访问,并且为表插入创建了瓶颈。

DB2(通常是 iSeries 上的标准)有一个称为SEQUENCE的东西,您可以查询它来生成您的 id。
我对冷融合一无所知,但是像这样:

<cfquery name="qNextId" datasource="myDS"> 
    SELECT NEXTVAL FOR [sequencename] AS NextId 
    FROM Sysibm.Sysdummy1
</cfquery> 

<cfset myId = qNextId.NextId /> 
于 2012-03-06T18:02:29.837 回答
3

您可以使用 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在会话中使用了表达式之后。

于 2012-03-06T23:23:20.137 回答