У меня есть хранимая процедура вставки записи в таблицу в нашем хранилище данных Teradata со следующим утверждением:Capture Ошибка вставки в Teradata
INSERT INTO UAT_AUDIT_VIEWS.AUDIT_BATCH(
BATCH_KEY
,AUDIT_STATUS_KEY
,BATCH_START_DATETIME
,BATCH_END_DATETIME
,BATCH_OWNER
,BATCH_EXECUTION_START_DATETIME
,BATCH_EXECUTION_END_DATETIME
)
VALUES(
(SELECT COALESCE(MAX(BATCH_KEY),0)+1 FROM UAT_AUDIT_VIEWS.AUDIT_BATCH)
,5 --PENDING
,'1900-01-01 00:00:00'
,'2999-12-31 00:00:00'
,:P_BATCH_OWNER
,CURRENT_TIMESTAMP
,'2999-12-31 00:00:00'
);
Обратите внимание, что у меня есть единственность ограничение на первичный ключ BATCH_KEY. В некоторых случаях моя инструкция insert не выполнялась, поскольку первичный ключ уже существует в таблице. Когда это произойдет, я хочу, чтобы моя хранимая процедура зациклилась и повторила попытку вставки до тех пор, пока она не будет успешной.
Я попробовал несколько решения с использованием следующим, но безуспешно:
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
, чтобы избежать хранимую процедуры потерпеть неудачу, когда вставка терпит неудачу- A
WHILE DO
петли, чтобы повторить попытку Вкладыша
Не могли бы вы описать, как бы вы справились с таким сценарием? Вот упрощенный вариант процедуры тестирования хранятся я построил, чтобы проверить это (который не работает):
REPLACE PROCEDURE DEV_AUDIT_NEW.ARO_TEST_INSERT()
BEGIN
DECLARE V_BATCH_KEY_CREATED VARCHAR(100);
DECLARE V_COUNTER SMALLINT DEFAULT 1;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
SET V_BATCH_KEY_CREATED = NULL;
WHILE V_BATCH_KEY_CREATED IS NULL
DO
INSERT INTO DEV_AUDIT_NEW.AUDIT_BATCH_TEST_LOG(LOG_DESC) VALUES(V_BATCH_KEY_CREATED);
INSERT INTO DEV_AUDIT_NEW.AUDIT_BATCH_TEST(BATCH_KEY,BATCH_OWNER) VALUES(V_COUNTER,'B');
SELECT BATCH_KEY
INTO :V_BATCH_KEY_CREATED
FROM DEV_AUDIT_NEW.AUDIT_BATCH_TEST
WHERE BATCH_KEY=V_COUNTER AND BATCH_OWNER='B';
SET V_COUNTER=V_COUNTER+1;
INSERT INTO DEV_AUDIT_NEW.AUDIT_BATCH_TEST_LOG(LOG_DESC) VALUES(V_BATCH_KEY_CREATED);
END WHILE;
END;
Ключ может существовать только при запуске SP параллельно. Вместо того, чтобы решать проблемы с параллелизмом, вы должны просто переключиться на блокировку WRITE: 'LOCK TABLE UAT_AUDIT_VIEWS.AUDIT_BATCH ДЛЯ WRITE INSERT ...' – dnoeth
У меня есть несколько команд, которые вызывают параллельную хранимую процедуру. Мы внедрили WRITE LOCK в качестве первого решения, но в конечном итоге это привело к возникновению проблем с блокировкой при одновременном доступе. Вот почему я хотел бы удалить его, захватить ошибку вставки и повторить попытку. Если у вас есть другие варианты, мне было бы интересно? –
Вставка, которую вы опубликовали, не может создавать взаимоблокировки как есть при параллельном запуске с блокировкой WRITE на уровне таблицы. Другое решение (которое масштабируется лучше) основано на таблице последовательности с одной строкой для этой таблицы, сохраняющей максимальное значение, ваш SP читает текущее значение, увеличивает его на единицу и записывает обратно. – dnoeth