Добавление записи
Функция
Определение запроса добавления записи в таблицу.
Спецификация
::=::=::=::=::=::=::=::=| NULL
| DEFAULT
| литерал
| имя последовательности.{currval|nextval}
| GUID
| USER
| SYSDATE
| LASTROWID
| LAST_AUTOINC
| SQL-параметр
| хранимая процедура
| EXTFILE (имя файла[, имя фильтра])
::=::=::=::=Синтаксические правила
-
Опция
< метка доступа >поддерживается только в СУБД ЛИНТЕР БАСТИОН. -
< Имя объекта >должно задавать пользовательскую базовую или таблицу «в памяти» или обновляемое пользовательское представление. -
Допустимые привилегии для
< объекта >, заданного< именем объекта >, должны включатьINSERT. -
< Имена столбцов >должны указывать на столбцы< объекта >, заданного< именем объекта >, один и тот же столбец не должен быть указан более одного раза. -
< Имя столбца >должно задавать реальный столбец< объекта >. Указание псевдостолбцов (типаROWIDилиROWTIME) не допускается. -
Отсутствие
< имен столбцов >подразумевает неявную спецификацию списка, идентифицирующего все столбцы в< имени объекта >согласно их позициям, указанным при создании таблицы.create table tab1 (i int, vc varchar(10) default 'unknown', b byte(5)); insert into tab1 values (1,'System', hex('00fc6733da')); insert into tab1 values (12,default, hex('01cc34abee')); insert into tab1 values (34,default, null); select * from tab1; | 1 | System | 00fc6733da | | 12 | unknown | 01CC34ABEE | | 34 | unknown | NULL | -
Количество значений в
< конструкторе данных >должно быть равно числу столбцов в явном или подразумеваемом< списке столбцов >. При этом считается, что i-е значение относится к i-му столбцу.create table tab1 (i int autoinc, vc varchar(50) not null, n numeric default 0, d date, bol boolean); insert into tab1(vc, d, bol) values ('АКБ "Промстройбанк"', to_date('23.04.2000','dd.mm.yyyy'), false); -
Если в заданном
< списке столбцов >не указаны все столбцы< объекта >, то для не упомянутых столбцов заносятся их значения по умолчанию. -
Опция
VALUESпозволяет использовать один или несколько списков вставляемых значений данных. -
Максимальное количество
< конструкторов данных >в опцииVALUES(т.е. добавляемых одновременно записей) в одном< запросе добавления >ограничено допустимой длиной текста SQL-запроса (не более 32 Кбайта).create or replace table tst (inv_num int, name char(10)); insert into tst (inv_num, name) values (67,'Компьютер'), (88,'Принтер'), (678,'Клавиатура'); select * from tst; INV_NUM NAME ------- ---- | 67|Компьютер | | 88|Принтер | | 678|Клавиатура|
-
В опции VALUES для значения элемента
< конструктора данных >разрешены любые выражения, не содержащие обращений к столбцам< объекта >, например: операторSELECT(в том числе в виде< table-запроса >и< value-запроса >), вызов пользовательской функции, не содержащей SQL-запросов и т.д.CREATE OR REPLACE TABLE Items ( item_no INT PRIMARY KEY, maker CHAR(10), type CHAR(10) DEFAULT 'PC', value INT ); CREATE OR REPLACE TABLE Printer ( code INT PRIMARY KEY, model INT); INSERT INTO PRINTER VALUES (1, 100), (77, 7700); INSERT INTO Items VALUES (1, 'A', 'Laptop', 12), (2, 'B', DEFAULT, NULL), (3, 'C', 'Printer', (SELECT CAST(model AS INT) FROM Printer WHERE code=1)), (4, 'C', 'Printer', (SELECT CAST(model AS INT) FROM Printer WHERE code=77)); -
Если указан
< подзапрос >, то количество столбцов таблицы, порождаемой этим< подзапросом >, должно быть равно числу столбцов в явном или подразумеваемом< списке столбцов >. При этом i-й столбец< подзапроса >относится к i-ому столбцу< объекта >.create table tab1 (i int, "Модель" varchar(20)); insert into tab1 select personid, model from auto; create table tab1 (i int, "Модель" varchar(20), d date); insert into tab1(I, "Модель") select personid, model from auto;
или
insert into tab1(I, "Модель") (select personid, model from auto);
-
Если значение i-го элемента опции
VALUESне является NULL-значением, то оно должно позволять автоматически преобразовывать его к типу i-го элемента списка столбцов. Автоматическое преобразование выполняется для следующих пар типов:-
SMALLINT, INT, BIGINT, DECIMAL – все между собой;
-
REAL, DOUBLE – между собой;
-
SMALLINT, INT, BIGINT, DECIMAL преобразуются в REAL, DOUBLE;
-
все строковые типы между собой, но только значение меньшей или равной длины должно вставляться в столбец большей или равной длины;
-
строка, содержащая дату и/или время, преобразуется в DATE.
-
-
Для присвоения NULL-значений столбцу типа EXTFILE допускается использование конструкции EXTFILE (NULL).
create table tab1 (i int, ext1 extfile root 'c:\linter\ext', ext2 extfile); insert into tab1(i, ext1, ext2) values (1, null, extfile(null));
-
Добавляемое
< значение >может быть логическим значением.create or replace table tst (i int, b boolean); insert into tst values (1,TRUE); insert into tst values (2, CAST (NULL as BOOLEAN)); insert into tst values (3, 2< 1); select * from tst; I B - - | 1 | T | | 2 | | | 3 | F |
-
Если задана опция
DEFAULT VALUES, столбцам присваивается значение по умолчанию. Если для столбца не задано значение по умолчанию, и он может содержать NULL-значение, то вставляется NULL-значение; в противном случае запись не добавляется и выдается код завершения 901 («Не задано значение первичного ключа или NOT NULL столбца»). Транслятор SQL СУБД ЛИНТЕР не проверяет, действительно ли у столбца есть значение по умолчанию, а возможные ошибки выдаются ядром СУБД ЛИНТЕР.create table tab1 (i1 int, i2 int default 0, i3 int default 1000, i4 int default -1, vc varchar(20)); insert into tab1(i1, i2, i3, i4, vc) values (1, default, default, default, 'SYSTEM'); select * from tab1; |1 |0 |1000 |-1 |SYSTEM |
-
< SQL-параметр >может быть именованный «:имя параметра» или не именованный «?» (см. пункт «SQL-параметр»). -
Числовое значение
< значимого выражения >допускается представлять в виде строкового значения без использования оператора преобразования типа данных.create or replace table tst (i1 int, i2 int, i3 int, db1 double, db2 double); insert into tst values (15, '15', cast '15' as int, 103.545, '1.03545e+2'); select * from tst; | 15| 15| 15| 103.545| 103.545|
Общие правила
-
Добавление записей выполняется в следующей последовательности:
-
создается строка-кандидат, структура данных которой совпадает со структурой строки базовой таблицы. Если
< имя таблицы >идентифицирует представление, то в качестве базовой таблицы выступает та, из которой создано данное представление; -
все поля строки-кандидата заполняются значениями по умолчанию;
-
если задана спецификация
DEFAULT VALUES, строка-кандидат вставляется в базовую таблицу; -
для каждого столбца, указанного в
< списке столбцов >, значение в строке-кандидате заменяется вставляемым значением; -
строка-кандидат добавляется в базовую таблицу.
-
-
Если
< конструктор данных >содержит добавление нескольких записей и одна из этих записей не может быть добавлена (например, переполнение значения, ограничение целостностиCHECKи т.п.), то процесс добавления прерывается на ошибочной записи с выдачей соответствующего кода завершения, а ранее добавленные записи удаляются. -
При добавлении в BLOB-столбец текстовых данных (типа
CHAR,VARCHAR,NCHAR,NCHAR VARYING) выполняется автоматическая перекодировка этих данных в кодировку BLOB-столбца, а бинарные данные добавляются «как есть»:create or replace table test(i int, bl blob character set "UCS2"); insert into test(i,bl) values (1, 'АБВГДЕЁЖ'); insert into test(i,bl) values (2, n'АБВГДЕЁЖ'); insert into test(i,bl) values (3, HEX('410042004300440045004600')); select i, lenblob(bl), getblobstr(bl, 1, 20) from test; | 1| 16|АБВГДЕЁЖ..| | 2| 16|АБВГДЕЁЖ..| | 3| 12|ABCDEF....| -
Если значение для AUTOROWID-столбца не задано при занесении записей в таблицу, содержащую AUTOROWID-столбец, то для каждой записи в него заносится значение, равное
ROWIDэтой записи (здесь возможен какINSERTодной записи, так иINSERT FROM SELECT). -
Если значение для AUTOROWID-столбца задано, то запись должна быть занесена в таблицу с
ROWID, равным указанному значению. Если означенныйROWIDзанят другой записью, либо указано недопустимое значениеROWID, то операция завершается с ошибкой. Здесь также возможен какINSERTодной записи, так иINSERT FROM SELECT. -
Если
< имя объекта >ссылается на необновляемый объект, будет зафиксирована исключительная ситуация 2162 («Данное представление не может быть обновлено»). -
При указании спецификации
DEFAULT VALUESавтоматически выполняются заданные свойства столбца (например, приAUTOINCзначение столбца увеличивается на заданную величину).create table tab1 ( i int autoinc, c char (10) default '???', d date default sysdate, n dec default 0); insert into tab1 default values; insert into tab1 default values; select * from tab1; |1 |??? |28.04.2003:13:10:15.00 |0.0 | |2 |??? |28.04.2003:13:10:15.00 |0.0 |
-
При занесении значения в столбец типа
DECIMALпроверяется, удовлетворяет ли оно значениямPRECISIONиSCALE, заданным для столбца. Если задано слишком много цифр дробной части, то число округляется; если задано слишком много цифр целой части, выдается код завершенияOVRDECIMAL.create table tab1 ( d1 dec(4,2), d2 dec(15,7)); insert into tab1 values (15.347, 45.12345678); select * from tab1; |15.35 |45.1234568 |
-
При присвоении по
INSERTзначенияCAST AS < строковый тип >некоторому столбцу без явного указания длины строкового типа длина делается равной длине столбца.create table tab1 (c varchar(2700)); insert into tab1 values (cast '12345' as char);
-
Если столбец имеет модификатор
AUTOINC, добавляемое значение должно быть больше всех ранее добавлявшихся в таблицу значений данного столбца.create table tab1 (i int autoinc); insert into tab1 default values; insert into tab1 values (100); select * from tab1; |1| |100|
-
Если столбец имеет модификатор
AUTOINC RANGE, то можно вставлять произвольные значения вне диапазонов.create table tab1 (i int autoinc range (1:100, 500:1000)); insert into tab1 default values; insert into tab1 values (400); select * from tab1; |1| |400|
-
Возвращаемое
< хранимой процедурой >значение должно быть скалярным (не курсорным) и иметь тип данных соответствующего столбца или приводимый к нему.Хранимая процедура: create or replace procedure insert_tst(in prm int) result char(5) code return to_char(prm*100);// end; Вставка значения, возвращаемого хранимой процедурой; create or replace table tst (id int autoinc, i int, ch char(10)); insert into tst (i, ch) values(100, '$'+insert_tst(5)); insert into tst (i, ch) values(200, '$'+insert_tst(? (int))); 7 select * from tst; | 1| 100|$500 | | 2| 200|$700 |
-
Конструкция
< ORDER BY-спецификация >задаёт порядок, в котором записи должны добавляться в таблицу.Примечание
В действительности, реальные значения
ROWIDдобавленных в таблицу записей во многих случаях будут не соответствовать порядку добавления записей. Соответствие будет в следующих случаях:-
если записи заносятся в пустую таблицу;
-
после очистки таблицы;
-
после сжатия таблицы (команда
PRESS); -
в таблице не было удаления записей.
CREATE OR REPLACE TABLE T1( i int); CREATE OR REPLACE TABLE T2( i int); insert into t2 (i) values(1); insert into t2 (i) values(2); insert into t2 (i) values(3); insert into t2 (i) values(4); insert into t2 (i) values(5); insert into t1 (i) select * from t2 order by 1 desc; select rowid, i from t1; ROWID I ----- - | 1| 5| | 2| 4| | 3| 3| | 4| 2| | 5| 1|
-
-
Параметр
< время >задает максимально допустимую продолжительность выполнения запроса (от 1 до 65535 сек.). Если запрос в отведенное для него время не был выполнен, его обработка прекращается с выдачей соответствующего кода завершения. -
Конструкция
WITH PRIORITY < приоритет >устанавливает заданный приоритет (значение в диапазоне от 0 до 255) выполняемому запросу. Если задать приоритет больше текущего приоритета пользователя, от имени которого подается запрос, то выдается код завершения 1022 («Нарушение привилегий»). -
Конструкция
WITH PRIORITY < приоритет >устанавливает приоритет только тому запросу, в котором она указана. На приоритет любых последующих запросов она не влияет. -
При вставке строки в таблицу, содержащую генерируемый столбец, вычисляется ассоциированное с ним
< логическое выражение >, и полученное значение становится значением этого столбца в добавляемой записи.create or replace table emp ( emp_no integer, emp_sal double, emp_bonus double, emp_total generated always as (emp_sal + emp_bonus));
При выполнении оператора добавления записи
insert into emp (emp_no, emp_sal, emp_bonus) values (1, 40000, 4000);
путем вычисления выражения
emp_sal + emp_bonusбудет автоматически сгенерировано значение столбца emp_total, и в таблицу emp будет добавлена запись со значениями (1, 40000, 4000, 44000). -
В добавляемой записи вместо явного значения генерируемого столбца можно использовать опцию
DEFAULT.Приведенные ниже insert-команды эквивалентны.
create or replace table tst ("Сумма" numeric, "Скидка" numeric, "Итого" generated always as (("Сумма"*(100-"Скидка")/100))); insert into tst ("Сумма", "Скидка") values (1000,5); insert into tst ("Сумма", "Скидка") values (2000,7); select * from tst; | 1000.0| 5.0| 950.0| | 2000.0| 7.0| 1860.0|insert into tst ("Сумма", "Скидка", "Итого") values (1000, 5, default); insert into tst ("Сумма", "Скидка", "Итого") values (2000, 7, default); select * from tst; | 1000.0| 5.0| 950.0| | 2000.0| 7.0| 1860.0| -
Добавление новых записей в циклическую таблицу из этой же таблицы через подзапрос (
INSERT INTO tab FROM SELECT tab) имеет некоторые особенности. Это связано с тем, что при попытке добавить первую запись в переполненную таблицу сначала происходит её автоматическое удаление. А когда ядро СУБД обращается за данными для добавления, выясняется, что исходной записи нет и данные брать уже неоткуда. Поэтому место первой удаленной записи в таблице занимает вторая запись из подзапроса, т.е. добавление записей из подзапроса происходит со сдвигом на одну запись, при этом первая запись подзапроса будет потеряна. -
Для таблиц «в памяти»
< запрос добавления >в режиме OPTIMISTIC не поддерживается (так же как и другие DML-запросы). -
Модификатор
WITH LOCKзаставляет блокировать добавляемую запись. Разблокирование добавленной записи выполняется после завершения транзакции (COMMIT/ROLLBACK).create or replace table tst (i int default 0, c char(20) default 'xxx'); insert into tst(i,c) values(100,'abc') with lock; insert into tst default values with lock; insert into tst (i,c) values (100,'abc'), (200, 'def') with lock; insert into tst (i,c) select personid, make from auto where rowid=100 with lock;
-
Накладываемая модификатором
WITH LOCKблокировка может подвергаться эскалации, т.е. если суммарное количество блокированных (по командамUPDATEиINSERT) в таблице записей превысит 1000, то блокировка записей сбрасывается и блокируется вся таблица (это означает, что с этого момента все вновь добавляемые записи считаются блокированными).Примечание
Добавляемая запись без модификатора
WITH LOCKне блокируется и становится сразу же видимой параллельно работающим транзакциям. -
Если добавляемая запись с модификатором
WITH LOCKссылается на заблокированную запись, то выдается код завершения 135 («Строка таблицы заблокирована другим пользователем»).create table tpk(i int primary key); create table tfk(i int references tpk); exclusive -- установили транзакционный режим insert into tpk values (1) with lock; -- здесь транзакции, которые пытаются читать таблицу tpk или только ее запись с i=1, будут ждать снятия блокировки -- транзакции, которые пытаются внести запись в таблицу tfk с i=1, ссылающиеся на добавленную запись, получат код завершения 135 commit; -- блокировка снимается
Примеры
-
Добавление данных в циклическую таблицу
create or replace table ct(i int); alter table ct set records limit 5; insert into ct values(1),(2),(3), (4),(5); select * from ct;
Этот select-запрос возвращает следующие 5 записей:
I - | 1| | 2| | 3| | 4| | 5|
-
insert into ct(i) select i+10 from ct; select * from ct;
Этот select-запрос возвращает 5 записей, из которых видно, что реально изменились только 4 записи:
I - | 12| | 13| | 14| | 15| | 5|
-
Добавление данных с метками мандатного доступа
username SYSTEM/MANAGER8 create level "НЕСЕКРЕТНО"=1; create level "ДСП"=2; grant DBA to B identified by '12345678'; alter user B LEVEL("НЕСЕКРЕТНО","НЕСЕКРЕТНО"); username B/12345678 ! Создание объектов БД (таблиц) и передача прав на них всем ! пользователям (разрешение всех действий по дискреционному доступу): create or replace table TB(I INT LEVEL("НЕСЕКРЕТНО", "НЕСЕКРЕТНО"), C CHAR(20) LEVEL("НЕСЕКРЕТНО", "НЕСЕКРЕТНО")) LEVEL("НЕСЕКРЕТНО", "НЕСЕКРЕТНО"); grant all on TB to PUBLIC; ! Добавление данных: insert into tb values(1,'one'); insert into tb##"НЕСЕКРЕТНО"#"ДСП" values(2,'two'); insert into tb##"НЕСЕКРЕТНО"#"НЕСЕКРЕТНО" values(3,'three');