Добавление записи
Функция
Определение запроса добавления записи в таблицу.
Спецификация
::=
::=
::=
::=
::=
::=
::=
::=
| 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');