Как можно автоматически увеличить столбец базы данных iSeries при вставке через SQL с нескольких веб-сайтов? - PullRequest
2 голосов
/ 06 марта 2012

Безумный вопрос. Я знаю. Вот сценарий:

Мой клиент имеет несколько веб-сайтов 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 />

Но я беспокоюсь о двух пользователях, одновременно попадающих в таблицу, и оба получают один и тот же "новый" идентификатор.

Есть мысли?

Ответы [ 3 ]

3 голосов
/ 06 марта 2012

В дополнение к ПОСЛЕДОВАТЕЛЬНОСТИ, отмеченной @ X-Zero, администратор IBM DB2 может поместить в базу данных автоматически увеличивающийся столбец, называемый IDENTITY.

create MYTABLE ...
(ID int 
    generated always as IDENTITY(Start with 1 
                                 Increment by 1)
... 
3 голосов
/ 07 марта 2012

Вы можете использовать объект 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 в своем сеансе.

3 голосов
/ 06 марта 2012

Особенно в веб-контексте, вы должны беспокоиться о одновременных пользователях.Есть две присущие проблемы с попыткой сгенерировать идентификатор с MAX() следующим образом:

  1. Вы не «синхронизируете» доступ, и два пользователя в итоге получают один и тот же идентификатор.
  2. Вы делаете «синхронизируете» доступ и создаете узкое место для вставок таблицы.

В DB2 (которая обычно является стандартной для iSeries) есть нечто, называемое SEQUENCE , к которому вы можете обратиться, чтобы сгенерировать свои идентификаторы.
Я ничего не знаю оcoldfusion, но как то так:

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

<cfset myId = qNextId.NextId /> 
...