вторник, 16 июля 2013 г.

Быстрая набивка тестовой таблицы в oracle

Мелкая заметка. Иногда надо быстренько заполнить данными какую-нибудь тестовую табличку в базе данных; в последний раз таковой оказалась rdbms oracle, а потому весь процесс для неё решил зафиксировать на будущее.

Итак. Обычно в качестве клиента к базам данных использую универсальный SQuirrel SQL client (нынче установлена версия 3.5), хотя, как показывает практика, иногда с ним бывают проблемы (см. далее по тексту). Ну, для этих целей отлично подойдёт и любой другой клиент. Итак, алиас создан, коннект удался, на экране чистый "лист" для sql.
--создаём таблицу с тремя простыми полями
CREATE TABLE sandbox.test (id NUMBER, f1 VARCHAR(255), f2 TIMESTAMP(6));
Далее можно бы сделать ограничение для первичного ключа:
ALTER TABLE sandbox.test ADD (CONSTRAINT pk_test PRIMARY KEY (id));
Но чтобы не заморачиваться с primary key, удобнее сделать последовательность и триггер:
--последовательность
CREATE SEQUENCE seq_test START WITH 1 ORDER CACHE 32;
--новый триггер
CREATE OR REPLACE TRIGGER trg_test_bi
BEFORE INSERT ON sandbox.test
FOR EACH ROW
BEGIN
            SELECT seq_test.nextval INTO :new.id FROM DUAL;
END;
/
Прим. Вроде бы, триггер простой и понятный. Тем не менее, в первый раз именно на этом месте возникла проблема. Триггер вроде как создавался, но оказывался в состоянии invalid и не работал. Разные эксперименты, попытки перекомпиляции типа ALTER TRIGGER trg_test_bi COMPILE; и другие танцы не помогали. Раскопать причину такого поведения не удалось. А вот запуск утилиты oracle sql plus (хоть она не особо дружелюбна к пользователю) помог - этот же код отработал на ура, и триггер успешно скомпилировался. Кто виноват - неизвестно.


Ну, и далее собственно вставка: 
DECLARE
            N NUMBER;
BEGIN
            N:=100000;
            FOR I IN 1..N LOOP
                        INSERT INTO sandbox.test(f1,f2) VALUES ('abcdef', systimestamp);
            END LOOP;
COMMIT;
END;
/
Отработает такой запрос со скоростью ~20k/sec.

Ещё одно (один?) прим. В конце каждой программной единицы - процедуры, триггера, функции, пакета - для oracle весьма важно видеть символ "/" (фетиш у него такой, наверное). Если этого не сделать, то oracle sql plus просто перейдёт на следующую строку и будет ожидать продолжения ввода. А squirrel при попытке выполнить код выдаст ошибку:
java.lang.IllegalArgumentException: No SQL selected for execution. Position: 0 
Вот такая вот фишка pl/sql. Ну, а squirrel'у ничего не остаётся, как такие фишки поддерживать...

Комментариев нет:

Отправить комментарий