Попытка избежать -803 в вставке DB2 - PullRequest
5 голосов
/ 13 января 2010

Я пытаюсь вставить одну строку, которая может существовать или не существовать. Я хотел бы избежать его выбора и / или получения -803, если он существует. Я провел некоторое исследование и попробовал игнорировать и оператор слияния, но продолжаю получать синтаксические ошибки на обоих. В любом случае я не пытаюсь скопировать данные из другой таблицы, поэтому объединение не совсем подходит.
Разве в DB2 SQL нет способа просто выполнить безошибочную вставку и не обходиться без кода? Другими словами, есть ли какой-то синтаксис вставки, который гарантирует, что данные будут добавлены, если они не существуют или вернут нулевой статус, даже если это так?

Ответы [ 4 ]

7 голосов
/ 12 мая 2010

MERGE является соответствующим, поскольку вы можете динамически указывать значения в предложении USING (см. Пример 5 в http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.ibm.db2.udb.admin.doc/doc/r0010873.htm).

Но MERGE - это функция DB2 V8.2! Вы, наверное, на V8.1, не так ли?

Если вы реализуете проверку существования следующим образом:

SELECT
if (found) UPDATE else INSERT

Остерегайтесь проблем параллелизма: два одновременно работающих потока могут оба не найти столбец, а затем оба пытаются вставить, даже если вокруг вышеуказанного кода есть транзакция. Чтобы этого не произошло, вам необходимо получить блокировку обновления с повторяемым чтением в приведенном выше операторе SELECT с использованием WITH RR USE AND KEEP UPDATE LOCKS.

2 голосов
/ 30 ноября 2011

Вы можете сделать это, используя таблицу sysibm.sysdummy (или лучше назвать двойной из Oracle или более поздних версий DB2). Это будет очень хорошо работать для случая, когда вы хотите вставить строку, которая не существует, но вернуть 0, если она существует. AFAIK, вы не можете обновить строку с помощью этого метода, вам нужно использовать слияние для этого.

Для этого вам понадобится первичный или уникальный ключ на вашем столе. Вы вставляете в таблицу, выбирая все ваши значения из двойного в процессе, где в вашей таблице нет строки, соответствующей вашему первичному или уникальному индексу.

insert into table (column1, column2, column3, column4, column5)
select 'A', 'B', 'C', 'D', 'E' from dual where not exists (select * from table where column1 = 'A');

Я нашел это очень полезным для случаев, когда у меня есть несколько процессов, вставляющих в таблицу, и я не могу гарантировать порядок этих вставок. Вы можете определить, была ли вставка успешной или нет, по возвращаемому значению, которое будет равно 1, если оно прошло успешно, или 0, если не

2 голосов
/ 07 декабря 2010

Вы можете выполнить оператор обновления, если он возвращает 0 обновленных результатов, а затем выполнить оператор вставки.

2 голосов
/ 13 января 2010

Короче, ответ - нет. В общем, все зависит от ограничений, которые вы установили на своем столе. Если вы попытаетесь выполнить вставку для таблицы, которая имеет уникальное ограничение для столбца, и уже существуют данные, которые вы пытаетесь вставить, вы получите ошибку в DB2 (и любой другой RDBMS).

В этом случае ваш лучший вариант - написать хранимую процедуру, которая проверяет, существует ли запись перед ее созданием.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...