Sqlиспользование insert select для построения внешнего соединения

Содержание

INSERT

SQL INSERT

Команда INSERT добавляет строки в таблицу или представление основной таблицы.

Синтаксис команды Sql INSERT

Синтаксис команды Insert

  • schema — идентификатор полномочий, обычно совпадающий с именем некоторого пользователя
  • table view — имя таблицы, в которую строки должны быть вставлены; если указано представление, то строки вставляются в основную таблицу представления
  • subquery_1 — подзапрос, который сервер обрабатывает тем же самым способом как представление
  • column — столбец таблицы или представления, в который для каждой вставленной строки вводится значение из фразы VALUES или подзапроса; если один из столбцов таблицы опускается из этого списка, значением столбца для вставленной строки является значение по умолчанию столбца, определенное при создании таблицы. Если полностью опускается список столбца, предложение VALUES или запрос должен определить значения для всех столбцов в таблице
  • VALUES — определяет строку значений, которые будут вставлены в таблицу или представление; значение должно быть определено в предложении VALUES для каждого столбца в списке столбцов
  • subquery_2 — подзапрос, который возвращает строки, вставляемые в таблицу; выборочный список этого подзапроса должен иметь такое же количество столбцов, как в списке столбцов утверждения INSERT

Утверждение INSERT с фразой VALUES добавляет одиночную строку к таблице. Эта строка содержит значения, определенные фразой VALUES.
Утверждение INSERT с подзапросом вместо фразы VALUES добавляет к таблице все строки, возвращенные подзапросом. Сервер обрабатывает подзапрос и вставляет каждую возвращенную строку в таблицу. Если подзапрос не выбирает никакие строки, сервер не вставляет никакие строки в таблицу.
Подзапрос может обратиться к любой таблице или представлению, включая целевую таблицу утверждения INSERT. Сервер назначает значения полям в новых строках, основанных на внутренней позиции столбцов в таблице и порядке значений фразы VALUES или в списке выбора запроса. Если какие-либо столбцы пропущены в списке столбцов, сервер назначает им значения по умолчанию, определенные при создании таблицы. Если любой из этих столбцов имеет NOT NULL ограничение то сервер возвращает ошибку, указывающую, что ограничение было нарушено и отменяет утверждение INSERT.
При выдаче утверждения INSERT включается любой INSERT — триггер, определенный на таблице.

INSERT INTO

INSERT INTO Пример 1

INSERT INTO dept VALUES (50, «ПРОДУКЦИЯ», «САН-ФРАНЦИСКО»);

INSERT INTO Customers (city, cname, cnum) VALUES (‘London’, ‘Hoffman’, 2001);

INSERT INTO Пример 2
Нижеприведенная команда копирует данные сотрудников фирмы, комисионные которых превышают 25% от дохода в таблицу bonus:

INSERT INTO bonus SELECT ename, job, sal, comm FROM emp WHERE comm > 0.25 * sal;

INSERT INTO Пример 3
Если нужно вставить NULL-значение, необходимо указать его как обычное значение следующим образом:

INSERT INTO Salespeople VALUES (1001,’Peel’,NULL,12);

INSERT INTO Пример 4
Команду INSERT можно применить для того, чтобы извлечь значения из одной таблицы и разместить их в другой, воспользовавшись для этого запросом. Для этого достаточно заменить предложение VALUES на соответствующий запрос:

INSERT INTO Londonstaff SELECT * FROM Salespeople WHERE city = ‘London’;

MySQL INSERT

Для вставки новых строк в базу данных MySQL используется команда INSERT, примеры команды INSERT приведены ниже:
INSERT INTO Пример 1.
Вставка новой строки в таблицу table_name.

INSERT INTO table_name VALUES (‘1′,’165′,’0′,’name’);

INSERT INTO Пример 2.
Вставка новой строки в таблицу table_name с указанием вставки данных в нужные нам колонки.

INSERT INTO table_name VALUES (‘1′,’165′,’0′,’name’);

В базе данных MySQL имеется возможность вставлять множество новых строк, используя одну команду INSERT.
INSERT INTO Пример 3.
Вставка несколько строк в таблицу table_name.

INSERT INTO table_name (tbl_id, chislo, chislotwo, name) VALUES (‘1′,’159′,’34’,’name1′), (‘2′,’14’,’61’,’name2′), (‘3′,’356′,’8′,’name3’);

Вы должны войти, чтобы оставить комментарий.

SQL-Урок 13. Добавление данных (INSERT INTO)

В предыдущих разделах мы рассматривали работу по получению данных с заранее созданных таблиц. Теперь пора разобрать, каким же образом мы можем создавать/удалять таблицы, добавлять новые записи и удалять старые. Для этих целей в SQL существуют такие операторы, как: CREATE — создает таблицу, ALTER — изменяет структуру таблицы, DROP — удаляет таблицу или поле, INSERT — добавляет данные в таблицу. Начнем знакомство с данной группой операторов из оператора INSERT.

1. Добавление целых строк

Как видно из названия, оператор INSERT используется для вставки (добавления) строк в таблицу базы данных. Добавление можно осуществить несколькими способами:

  • — добавить одну полную строку
  • — добавить часть строки
  • — добавить результаты запроса.

Итак, чтобы добавить новую строку в таблицу, нам необходимо указать название таблицы, перечислить названия колонок и указать значение для каждой колонки с помощью конструкции INSERT INTO название_таблицы (поле1, поле2 . ) VALUES (значение1, значение2 . ). Рассмотрим на примере.

INSERT INTO Sellers ( >VALUES (‘6’, ‘1st Street’, ‘Los Angeles’, ‘Harry Monroe’, ‘USA’)

Также можно изменять порядок указания названий колонок, однако одновременно нужно менять и порядок значений в параметре VALUES.

2. Добавление части строк

В предыдущем примере при использовании оператора INSERT мы явно отмечали имена столбцов таблицы. Используя данный синтаксис, мы можем пропустить некоторые столбцы. Это значит, что вы вводите значение для одних столбцов но не предлагаете их для других. Например:

INSERT INTO Sellers ( >VALUES (‘6’, ‘Los Angeles’, ‘Harry Monroe’)

В данном примере мы не указали значение для двух столбцов Address и Country . Вы можете исключать некоторые столбцы из оператора INSERT INTO, если это позволяет производить определение таблицы. В этом случае должно соблюдаться одно из условий: этот столбец определен как допускающий значение NULL (отсутствие какого-либо значения) или в определение таблицы указанное значение по умолчанию. Это означает, что, если не указано никакое значение, будет использовано значение по умолчанию. Если вы пропускаете столбец таблицы, которая не допускает появления в своих строках значений NULL и не имеет значения, определенного для использования по умолчанию, СУБД выдаст сообщение об ошибке, и это строка не будет добавлена.

3. Добавление отобранных данных

В предыдущей примерах мы вставляли данные в таблицы, прописывая их вручную в запросе. Однако оператор INSERT INTO позволяет автоматизировать этот процесс, если мы хотим вставлять данные из другой таблицы. Для этого в SQL существует такая кострукция как INSERT INTO . SELECT . . Данная конструкция позволяет одновременно выбирать данные из одной таблицы, и вставить их в другую. Предположим мы имеем еще одну таблицу Sellers_EU с перечнем продавцов нашего товара в Европе и нам нужно их добавить в общую таблицу Sellers. Структура этих таблиц одинакова (то же количество колонок и те же их названия), однако другие данные. Для этого мы можем прописать следующий запрос:

INSERT INTO Sellers ( >SELECT >FROM Sellers_EU

Нужно обратить внимание, чтобы значение внутренних ключей не повторялись (поле ID), в противном случае произойдет ошибка. Оператор SELECT также может включать предложения WHERE для фильтрации данных. Также следует отметить, что СУБД не обращает внимания на названия колонок, которые содержатся в операторе SELECT, для нее важно только порядок их расположения. Поэтому данные в первом указанном столбце, что были выбраны из-за SELECT, будут в любом случае заполнены в первый столбец таблицы Sellers, указанной после оператора INSERT INTO, независимо от названия поля.

4. Копирование данных из одной таблицы в другую

Часто при работе с базами данных возникает необходимость в создании копий любых таблиц, с целью резервирования или модификации. Чтобы сделать полную копию таблицы в SQL предусмотрен отдельный оператор SELECT INTO. Например, нам нужно создать копию таблицы Sellers, нужно будет прописать запрос следующим образом:

SELECT * INTO Sellers_new FROM Sellers

В отличие от предыдущей конструкции INSERT INTO . SELECT . , когда данные добавляются в существующую таблицу, конструкция SELECT . INTO . FROM . копирует данные в новую таблицу. Также можно сказать, что первая конструкция импортирует данные, а вторая — экспортирует. При использовании конструкции SELECT . INTO . FROM . следует учитывать следующее:

  • — можно использовать любые предложения в операторе SELECT, такие как GROUP BY и HAVING
  • — для добавления данных из нескольких таблиц можно использовать объединение
  • — данные возможно добавить только одну таблицу, независимо от того, из скольких таблиц они были взяты.

Select внутри insert

23.03.2020, 12:25

Использование INSERT + SELECT (скопировать данные внутри таблицы)
Здравствуйте, товарищи, уже 4 часа пытаюсь накидать запрос — какая то ерунда получается. Структура.

INSERT + SELECT
возможно ли в одном запросе добавить строку в таблицу и сразу потом вывести все существующие строки?

insert select
надо добавить в таблицу model(id_price,id_tb) записи из двух разных таблиц.Как это сделать?

select в insert-e
доброго времени суток, нужно сделать insert в базу по id-шкам которые вибираються select-ом.

INSERT SELECT
Есть две полностью идентичные таблицы, можно ли перенести все данные из второй в конец первой, не.

SQL — Оператор INSERT INTO SELECT

Оператор INSERT INTO SELECT копирует данные из одной таблицы и вставляет ее в другую таблицу. INSERT INTO SELECT требует, чтобы типы данных в исходной и целевой таблицах соответствовали.

Синтаксис INSERT IN SELECT

Скопировать все столбцы из одной таблицы в другую:

Скопировать только несколько столбцов из одной таблицы в другую таблицу:

Пример SQL INSERT INTO SELECT

Следующий оператор SQL копирует «clients» в «users» (столбцы, которые не заполнены данными, будет содержать NULL):

Sqlиспользование insert select для построения внешнего соединения

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

Общий синтаксис установки внешнего ключа на уровне таблицы:

Для создания ограничения внешнего ключа после FOREIGN KEY указывается столбец таблицы, который будет представляет внешний ключ. А после ключевого слова REFERENCES указывается имя связанной таблицы, а затем в скобках имя связанного столбца, на который будет указывать внешний ключ. После выражения REFERENCES идут выражения ON DELETE и ON UPDATE , которые задают действие при удалении и обновлении строки из главной таблицы соответственно.

Например, определим две таблицы и свяжем их посредством внешнего ключа:

В данном случае определены таблицы Customers и Orders. Customers является главной и представляет клиента. Orders является зависимой и представляет заказ, сделанный клиентом. Таблица Orders через столбец CustomerId связана с таблицей Customers и ее столбцом Id. То есть столбец CustomerId является внешним ключом, который указывает на столбец Id из таблицы Customers.

С помощью оператора CONSTRAINT можно задать имя для ограничения внешнего ключа:

ON DELETE и ON UPDATE

С помощью выражений ON DELETE и ON UPDATE можно установить действия, которые выполняются соответственно при удалении и изменении связанной строки из главной таблицы. В качестве действия могут использоваться следующие опции:

CASCADE : автоматически удаляет или изменяет строки из зависимой таблицы при удалении или изменении связанных строк в главной таблице.

SET NULL : при удалении или обновлении связанной строки из главной таблицы устанавливает для столбца внешнего ключа значение NULL . (В этом случае столбец внешнего ключа должен поддерживать установку NULL)

RESTRICT : отклоняет удаление или изменение строк в главной таблице при наличии связанных строк в зависимой таблице.

NO ACTION : то же самое, что и RESTRICT .

SET DEFAULT : при удалении связанной строки из главной таблицы устанавливает для столбца внешнего ключа значение по умолчанию, которое задается с помощью атрибуты DEFAULT. Несмотря на то, что данная опция в принципе доступна, однако движок InnoDB не поддерживает данное выражение.

Каскадное удаление

Каскадное удаление позволяет при удалении строки из главной таблицы автоматически удалить все связанные строки из зависимой таблицы. Для этого применяется опция CASCADE :

Подобным образом работает и выражение ON UPDATE CASCADE . При изменении значения первичного ключа автоматически изменится значение связанного с ним внешнего ключа. Однако поскольку первичные ключи изменяются очень редко, да и с принципе не рекомендуется использовать в качестве первичных ключей столбцы с изменяемыми значениями, то на практике выражение ON UPDATE используется редко.

Установка NULL

При установки для внешнего ключа опции SET NULL необходимо, чтобы столбец внешнего ключа допускал значение NULL:

SQL JOIN — соединение таблиц базы данных

Оператор языка SQL JOIN предназначен для соединения двух или более таблиц базы данных по совпадающему условию. Этот оператор существует только в реляционных базах данных. Именно благодаря JOIN реляционные базы данных обладают такой мощной функциональностью, которая позволяет вести не только хранение данных, но и их, хотя бы простейший, анализ с помощью запросов. Разберём основные нюансы написания SQL-запросов с оператором JOIN, которые являются общими для всех СУБД (систем управления базами данных). Для соединения двух таблиц оператор SQL JOIN имеет следующий синтаксис:

После одного или нескольких звеньев с оператором JOIN может следовать необязательная секция WHERE или HAVING, в которой, также, как в простом SELECT-запросе, задаётся условие выборки. Общим для всех СУБД является то, что в этой конструкции вместо JOIN может быть указано INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN, CROSS JOIN (или, как вариант, запятая).

INNER JOIN (внутреннее соединение)

Запрос с оператором INNER JOIN предназначен для соединения таблиц и вывода результирующей таблицы, в которой данные полностью пересекаются по условию, указанному после ON.

То же самое делает и просто JOIN. Таким образом, слово INNER — не обязательное.

Пример 1. Есть база данных портала объявлений. В ней есть таблица Categories (категории объявлений) и Parts (части, или иначе — рубрики, которые и относятся к категориям). Например, части Квартиры, Дачи относятся к категории Недвижимость, а части Автомобили, Мотоциклы — к категории Транспорт. Эти таблицы с заполненными данными имеют следующий вид.

Part_ID Part Cat
1 Квартиры 505
2 Автомашины 205
3 Доски 10
4 Шкафы 30
5 Книги 160
Cat_ID Cat_name Price
10 Стройматериалы 105,00
505 Недвижимость 210,00
205 Транспорт 160,00
30 Мебель 77,00
45 Техника 65,00

Заметим, что в таблице Parts Книги имеют Cat — ссылку на категорию, которой нет в таблице Categories, а в таблице Categories Техника имеет Cat_ID — первичный ключ, ссылки на который нет в таблице Parts. Требуется соединить данные этих двух таблиц так, чтобы в результирующей таблице были поля Part (Часть), Cat (Категория) и Price (Цена подачи объявления) и чтобы данные полностью пересекались по условию. Условие — совпадение идентификатора категории в таблице Categories и ссылки на категорию в таблице Parts. Для этого пишем следующий запрос:

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

Part Cat Price
Квартиры 505 210,00
Автомашины 205 160,00
Доски 10 105,00
Шкафы 30 77,00

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

В ряде случаев при соединениях таблиц составить менее громоздкие запросы можно с помощью предиката EXISTS и без использования JOIN.

Написать запросы SQL с JOIN самостоятельно, а затем посмотреть решения

Есть база данных «Театр». Таблица Play содержит данные о постановках. Таблица Team — о ролях актёров. Таблица Actor — об актёрах. Таблица Director — о режиссёрах. Поля таблиц, первичные и внешние ключи можно увидеть на рисунке ниже (для увеличения нажать левой кнопкой мыши).

Пример 2. Определить самого востребованного актёра за последние 5 лет.

Оператор JOIN использовать 2 раза. Использовать COUNT(), CURDATE(), LIMIT 1.

Пример 3. Вывести список актеров, которые в одном спектакле играют более одной роли, и количество их ролей.

Оператор JOIN использовать 1 раз. Использовать HAVING, GROUP BY.

Подсказка. Оператор HAVING применяется к числу ролей, подсчитанных агрегатной функцией COUNT.

LEFT OUTER JOIN (левое внешнее соединение)

Запрос с оператором LEFT OUTER JOIN предназначен для соединения таблиц и вывода результирующей таблицы, в которой данные полностью пересекаются по условию, указанному после ON, и дополняются записями из первой по порядку (левой) таблицы, даже если они не соответствуют условию. У записей левой таблицы, которые не соответствуют условию, значение столбца из правой таблицы будет NULL (неопределённым).

Пример 4. База данных и таблицы — те же, что и в примере 1.

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

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

Part Cat Price
Квартиры 505 210,00
Автомашины 205 160,00
Доски 10 105,00
Шкафы 30 77,00
Книги 160 NULL

В результирующей таблице, в отличие от таблицы из примера 1, есть Книги, но значение столбца Цены (Price) у них — NULL, так как эта запись имеет идентификатор категории, которой нет в таблице Categories.

RIGHT OUTER JOIN (правое внешнее соединение)

Запрос с оператором RIGHT OUTER JOIN предназначен для соединения таблиц и вывода результирующей таблицы, в которой данные полностью пересекаются по условию, указанному после ON, и дополняются записями из второй по порядку (правой) таблицы, даже если они не соответствуют условию. У записей правой таблицы, которые не соответствуют условию, значение столбца из левой таблицы будет NULL (неопределённым).

Пример 5. База данных и таблицы — те же, что и в предыдущих примерах.

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

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

Part Cat Price
Квартиры 505 210,00
Автомашины 205 160,00
Доски 10 105,00
Шкафы 30 77,00
NULL 45 65,00

В результирующей таблице, в отличие от таблицы из примера 1, есть запись с категорией 45 и ценой 65,00, но значение столбца Части (Part) у неё — NULL, так как эта запись имеет идентификатор категории, на которую нет ссылок в таблице Parts.

FULL OUTER JOIN (полное внешнее соединение)

Запрос с оператором FULL OUTER JOIN предназначен для соединения таблиц и вывода результирующей таблицы, в которой данные полностью пересекаются по условию, указанному после ON, и дополняются записями из первой (левой) и второй (правой) таблиц, даже если они не соответствуют условию. У записей, которые не соответствуют условию, значение столбцов из другой таблицы будет NULL (неопределённым).

Пример 6. База данных и таблицы — те же, что и в предыдущих примерах.

Для получения результирующей таблицы, в которой данные из двух таблиц полностью пересекаются по условию и дополняются всеми данными как из таблицы Parts, так и из таблицы Categories, которые не соответствуют условию, пишем следующий запрос:

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

Part Cat Price
Квартиры 505 210,00
Автомашины 205 160,00
Доски 10 105,00
Шкафы 30 77,00
Книги 160 NULL
NULL 45 65,00

В результирующей таблице есть записи Книги (из левой таблицы) и с категорией 45 (из правой таблицы), причём у первой из них неопределённая цена (столбец из правой таблицы), а у второй — неопределённая часть (столбец из левой таблицы).

Псевдонимы соединяемых таблиц

В предыдущих запросах мы указывали с названиями извлекаемых столбцов из разных таблиц полные имена этих таблиц. Такие запросы выглядят громоздко: одно и то же слово повторяется несколько раз. Нельзя ли как-то упростить конструкцию? Оказывается, можно. Для этого следует использовать псевдонимы таблиц — их сокращённые имена. Псевдоним может состоять и из одной буквы. Возможно любое количество букв в псевдониме, главное, чтобы запрос после сокращения был понятен Вам самим. Общее правило: в секции запроса, определяющей соединение, то есть вокруг слова JOIN нужно указать полные имена таблиц, а за каждым именем должен следовать псевдоним таблицы.

Пример 7. Переписать запрос из примера 1 с использованием псевдонимов соединяемых таблиц.

Запрос будет следующим:

Запрос вернёт то же самое, что и запрос в примере 1, но он гораздо компактнее.

JOIN и соединение более двух таблиц

Реляционные базы данных должны подчиняться требованиям целостности и неизбыточности данных, в связи с чем данные об одном бизнес-процессе могут содержаться не только в одной, двух, но и в трёх и более таблицах. В этих случаях для анализа данных используются цепочки соединённых таблиц: например, в одной (первой) таблице содержится некоторый количественный показатель, вторую таблицу с первой и третьей связывают внешние ключи — данные пересекаются, но только третья таблица содержит условие, в зависимости от которого может быть выведен количественный показатель из первой таблицы. И таблиц может быть ещё больше. При помощи оператора SQL JOIN в одном запросе можно соединить большое число таблиц. В таких запросах за одной секцией соединения следует другая, причём каждый следующий JOIN соединяет со следующей таблицей таблицу, которая была второй в предыдущем звене цепочки. Таким образом, синтаксис SQL запроса для соединения более двух таблиц следующий:

Пример 8. База данных — та же, что и в предыдущих примерах. К таблицам Categories и Parts в этом примере добавится таблица Ads, содержащая данные об опубликованных на портале объявлениях. Приведём фрагмент таблицы Ads, в котором среди записей есть записи о тех объявлениях, срок публикации которых истекает 2020-04-02.

A_Id Part_ID Date_start Date_end Text
21 1 ‘2020-02-11’ ‘2020-04-20’ «Продаю. «
22 1 ‘2020-02-11’ ‘2020-05-12’ «Продаю. «
. . . . .
27 1 ‘2020-02-11’ ‘2020-04-02’ «Продаю. «
28 2 ‘2020-02-11’ ‘2020-04-21’ «Продаю. «
29 2 ‘2020-02-11’ ‘2020-04-02’ «Продаю. «
30 3 ‘2020-02-11’ ‘2020-04-22’ «Продаю. «
31 4 ‘2020-02-11’ ‘2020-05-02’ «Продаю. «
32 4 ‘2020-02-11’ ‘2020-04-13’ «Продаю. «
33 3 ‘2020-02-11’ ‘2020-04-12’ «Продаю. «
34 4 ‘2020-02-11’ ‘2020-04-23’ «Продаю. «
Илон Маск рекомендует:  Перенаправление stdout в область памяти (или файл)

Представим, что сегодня ‘2020-04-02’, то есть это значение принимает функция CURDATE() — текущая дата. Требуется узнать, к каким категориям принадлежат объявления, срок публикации которых истекает сегодня. Названия категорий есть только в таблице CATEGORIES, а даты истечения срока публикации объявлений — только в таблице ADS. В таблице PARTS — части категорий (или проще, подкатегории) опубликованных объявлений. Но внешним ключом Cat_ID таблица PARTS связана с таблицей CATEGORIES, а таблица ADS связана внешним ключом Part_ID с таблицей PARTS. Поэтому соединяем в одном запросе три таблицы и этот запрос можно с максимальной корректностью назвать цепочкой.

Запрос будет следующим:

Результат запроса — таблица, содержащая названия двух категорий — «Недвижимость» и «Транспорт»:

Cat_name
Недвижимость
Транспорт

CROSS JOIN (перекрестное соединение)

Использование оператора SQL CROSS JOIN в наиболее простой форме — без условия соединения — реализует операцию декартова произведения в реляционной алгебре. Результатом такого соединения будет сцепление каждой строки первой таблицы с каждой строкой второй таблицы. Таблицы могут быть записаны в запросе либо через оператор CROSS JOIN, либо через запятую между ними.

Пример 9. База данных — всё та же, таблицы — Categories и Parts. Реализовать операцию декартова произведения этих двух таблиц.

Запрос будет следующим:

Или без явного указания CROSS JOIN — через запятую:

Запрос вернёт таблицу из 5 * 5 = 25 строк, фрагмент которой приведён ниже:

Cat_ID Cat_name Price Part_ID Part Cat
10 Стройматериалы 105,00 1 Квартиры 505
10 Стройматериалы 105,00 2 Автомашины 205
10 Стройматериалы 105,00 3 Доски 10
10 Стройматериалы 105,00 4 Шкафы 30
10 Стройматериалы 105,00 5 Книги 160
. . . . . .
45 Техника 65,00 1 Квартиры 505
45 Техника 65,00 2 Автомашины 205
45 Техника 65,00 3 Доски 10
45 Техника 65,00 4 Шкафы 30
45 Техника 65,00 5 Книги 160

Как видно из примера, если результат такого запроса и имеет какую-либо ценность, то это, возможно, наглядная ценность в некоторых случаях, когда не требуется вывести структурированную информацию, тем более, даже самую простейшую аналитическую выборку. Кстати, можно указать выводимые столбцы из каждой таблицы, но и тогда информационная ценность такого запроса не повысится.

Но для CROSS JOIN можно задать условие соединения! Результат будет совсем иным. При использовании оператора «запятая» вместо явного указания CROSS JOIN условие соединения задаётся не словом ON, а словом WHERE.

Пример 10. Та же база данных портала объявлений, таблицы Categories и Parts. Используя перекрестное соединение, соединить таблицы так, чтобы данные полностью пересекались по условию. Условие — совпадение идентификатора категории в таблице Categories и ссылки на категорию в таблице Parts.

Запрос будет следующим:

Запрос вернёт то же самое, что и запрос в примере 1:

Part Cat Price
Квартиры 505 210,00
Автомашины 205 160,00
Доски 10 105,00
Шкафы 30 77,00

И это совпадение не случайно. Запрос c перекрестным соединением по условию соединения полностью аналогичен запросу с внутренним соединением — INNER JOIN — или, учитывая, что слово INNER — не обязательное, просто JOIN.

Таким образом, какой вариант запроса использовать — вопрос стиля или даже привычки специалиста по работе с базой данных. Возможно, перекрёстное соединение с условием для двух таблиц может представляться более компактным. Но преимущество перекрестного соединения для более чем двух таблиц (это также возможно) весьма спорно. В этом случае WHERE-условия пересечения перечисляются через слово AND. Такая конструкция может быть громоздкой и трудной для чтения, если в конце запроса есть также секция WHERE с условиями выборки.

Sqlиспользование insert select для построения внешнего соединения

Рассмотренное в п.3.2.3 естественное соединение двух таблиц не включает тех строк какой-либо из них, для которых нет соответствующих строк в другой таблице. Например, если в таблицу Блюда были занесены под номером 34 сведения о Шашлыке, а рецепт его приготовления не был занесен в таблицу Рецепты, то при загрузке их естественного соединения в таблицу Временная:

в ней не окажется строки с Шашлыком (в таблице Рецепты не обнаружен код 34, и строка с этим кодом исключена из результата).

Следовательно, в некотором смысле можно считать, что при обычном соединении теряется информация для таких несоответствующих строк. Однако иногда (как и в приведенном примере) может потребоваться способность сохранить эту информацию. В этом случае можно воспользоваться так называемым внешним соединением:

В результате будет создана базовая таблица

Вид Блюдо Рецепт
Закуска Салат летний Помидоры и яблоки нарезать.
Закуска Салат мясной Вареное охлажденное мясо, .
. . .
Напиток Кофе черный Кофеварку или кастрюлю спо.
Напиток Кофе на молоке Сварить черный кофе, как .
Горячее Шашлык .

где первые 33 строки соответствуют первому INSERT и представляют собой проекцию естественного соединения таблиц Блюда и Рецепты по кодам блюд (БЛ), включающую три столбца. Последняя строка результата соответствует второму INSERT и сохраняет информацию о блюде Шашлык, рецепт котого пока не введен в таблицу Рецепты.

Заметим, что для внешнего соединения нужны два отдельных INSERT. SELECT. Однако тот же результат можно получить и одним INSERT. SELECT, используя фразу UNION, объединяющую предложения SELECT из двух INSERT:

Инструкция INSERT (Transact-SQL) INSERT (Transact-SQL)

ОБЛАСТЬ ПРИМЕНЕНИЯ: SQL Server База данных SQL Azure Azure Synapse Analytics (хранилище данных SQL) Parallel Data Warehouse APPLIES TO: SQL Server Azure SQL Database Azure Synapse Analytics (SQL DW) Parallel Data Warehouse

Добавляет одну или несколько строк в таблицу или представление SQL Server SQL Server . Adds one or more rows to a table or a view in SQL Server SQL Server . Примеры см. в разделе Примеры. For examples, see Examples.

Синтаксис Syntax

Аргументы Arguments

WITH WITH
Определяет временный именованный результирующий набор, также называемый обобщенным табличным выражением, определенным в области инструкции INSERT. Specifies the temporary named result set, also known as common table expression, defined within the scope of the INSERT statement. Результирующий набор получается из инструкции SELECT. The result set is derived from a SELECT statement. Дополнительные сведения см. в разделе WITH common_table_expression (Transact-SQL). For more information, see WITH common_table_expression (Transact-SQL).

TOP (expression) [ PERCENT ] TOP (expression) [ PERCENT ]
Задает число или процент вставляемых случайных строк. Specifies the number or percent of random rows that will be inserted. expression может быть либо числом, либо процентом от числа строк. expression can be either a number or a percent of the rows. Дополнительные сведения см. в разделе TOP (Transact-SQL). For more information, see TOP (Transact-SQL).

INTO INTO
Необязательное ключевое слово, которое можно использовать между ключевым словом INSERT и целевой таблицей. Is an optional keyword that can be used between INSERT and the target table.

server_name server_name
Применимо к: с SQL Server 2008 SQL Server 2008 до SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2008 SQL Server 2008 through SQL Server 2020 SQL Server 2020 .

Имя связанного сервера, на котором расположены таблица или представление. Is the name of the linked server on which the table or view is located. server_name может указываться как имя связанного сервера или с помощью функции OPENDATASOURCE. server_name can be specified as a linked server name, or by using the OPENDATASOURCE function.

Когда server_name указывается как имя связанного сервера, необходимо указать database_name и schema_name. When server_name is specified as a linked server, database_name and schema_name are required. Если server_name указано с помощью OPENDATASOURCE, то аргументы database_name и schema_name могут применяться не ко всем источникам данных, в зависимости от возможностей поставщика OLE DB, который обращается к удаленному объекту. When server_name is specified with OPENDATASOURCE, database_name and schema_name may not apply to all data sources and is subject to the capabilities of the OLE DB provider that accesses the remote object.

database_name database_name
Применимо к: с SQL Server 2008 SQL Server 2008 до SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2008 SQL Server 2008 through SQL Server 2020 SQL Server 2020 .

Имя базы данных. Is the name of the database.

schema_name schema_name
Имя схемы, которой принадлежит таблица или представление. Is the name of the schema to which the table or view belongs.

table_or view_name table_or view_name
Имя таблицы или представления, которые принимают данные. Is the name of the table or view that is to receive the data.

В качестве источника таблицы в инструкции INSERT можно использовать табличную переменную внутри своей области. A table variable, within its scope, can be used as a table source in an INSERT statement.

Представление, на которое ссылается аргумент table_or_view_name, должно быть обновляемым и ссылаться только на одну базовую таблицу в предложении FROM в представлении. The view referenced by table_or_view_name must be updatable and reference exactly one base table in the FROM clause of the view. Например, инструкция INSERT в многотабличном представлении должна использовать аргумент column_list, который ссылается только на столбцы из одной базовой таблицы. For example, an INSERT into a multi-table view must use a column_list that references only columns from one base table. Дополнительные сведения об обновляемых представлениях см. в разделе CREATE VIEW (Transact-SQL). For more information about updatable views, see CREATE VIEW (Transact-SQL).

rowset_function_limited rowset_function_limited
Применимо к: с SQL Server 2008 SQL Server 2008 до SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2008 SQL Server 2008 through SQL Server 2020 SQL Server 2020 .

Либо функция OPENQUERY, либо функция OPENROWSET. Is either the OPENQUERY or OPENROWSET function. Использование этих функций зависит от возможностей поставщика OLE DB, который обращается к удаленному объекту. Use of these functions is subject to the capabilities of the OLE DB provider that accesses the remote object.

WITH ( [. n ] ) WITH ( [. n ] )
Задает одно или несколько табличных указаний, разрешенных для целевой таблицы. Specifies one or more table hints that are allowed for a target table. Ключевое слово WITH и круглые скобки обязательны. The WITH keyword and the parentheses are required.

Нельзя использовать подсказки READPAST, NOLOCK, и READUNCOMMITTED. READPAST, NOLOCK, and READUNCOMMITTED are not allowed. Дополнительные сведения о табличных указаниях см. в разделе Табличные указания (Transact-SQL). For more information about table hints, see Table Hints (Transact-SQL).

Возможность указать подсказки HOLDLOCK, SERIALIZABLE, READCOMMITTED, REPEATABLEREAD или UPDLOCK в целевых таблицах инструкций INSERT будет удалена в будущих версиях SQL Server SQL Server . The ability to specify the HOLDLOCK, SERIALIZABLE, READCOMMITTED, REPEATABLEREAD, or UPDLOCK hints on tables that are targets of INSERT statements will be removed in a future version of SQL Server SQL Server . Эти указания не влияют на производительность инструкций INSERT. These hints do not affect the performance of INSERT statements. Избегайте применять их в новых разработках и запланируйте внесение изменений в приложения, использующие их в настоящее время. Avoid using them in new development work, and plan to modify applications that currently use them.

Указание подсказки TABLOCK для целевой таблицы инструкции INSERT приведет к тем же последствиям, что и указание подсказки TABLOCKX. Specifying the TABLOCK hint on a table that is the target of an INSERT statement has the same effect as specifying the TABLOCKX hint. К таблице будет применена монопольная блокировка. An exclusive lock is taken on the table.

(column_list) (column_list)
Список, состоящий из одного или нескольких столбцов, в которые вставляются данные. Is a list of one or more columns in which to insert data. Список column_list должен быть заключен в круглые скобки, а его элементы должны разделяться запятыми. column_list must be enclosed in parentheses and delimited by commas.

Если столбец не внесен в column_list, то компонент Компонент Database Engine Database Engine должен обеспечить значение, основанное на определении столбца; в противном случае строку нельзя будет загрузить. If a column is not in column_list, the Компонент Database Engine Database Engine must be able to provide a value based on the definition of the column; otherwise, the row cannot be loaded. Компонент Компонент Database Engine Database Engine автоматически задает значение для столбца, если столбец имеет следующие характеристики. The Компонент Database Engine Database Engine automatically provides a value for the column if the column:

Имеется свойство IDENTITY. Has an IDENTITY property. Используется следующее значение приращения для идентификатора. The next incremental identity value is used.

Имеется стандартное значение. Has a default. Используется стандартное значение для столбца. The default value for the column is used.

Имеет тип данных timestamp. Has a timestamp data type. В этом случае используется текущее значение отметки времени. The current timestamp value is used.

Допускает значение NULL. Is nullable. Используется значение NULL. A null value is used.

Вычисляемый столбец. Is a computed column. Используется вычисленное значение. The calculated value is used.

Аргумент column_list необходимо использовать, когда в столбец идентификаторов вставляются явно заданные значения, а параметру SET IDENTITY_INSERT необходимо присвоить значение ON для таблицы. column_list must be used when explicit values are inserted into an identity column, and the SET IDENTITY_INSERT option must be ON for the table.

Предложение OUTPUT OUTPUT Clause
Возвращает вставленные строки во время операции вставки. Returns inserted rows as part of the insert operation. Результаты могут возвращаться в обрабатывающее приложение или вставляться в таблицу или табличную переменную для дальнейшей обработки. The results can be returned to the processing application or inserted into a table or table variable for further processing.

Предложение OUTPUT не поддерживается инструкциями DML, которые ссылаются на локальные секционированные представления, распределенные секционированные представления или удаленные таблицы, или инструкциями INSERT, содержащими аргумент execute_statement. The OUTPUT clause is not supported in DML statements that reference local partitioned views, distributed partitioned views, or remote tables, or INSERT statements that contain an execute_statement. Предложение OUTPUT INTO не поддерживается в инструкциях INSERT, содержащих предложение . The OUTPUT INTO clause is not supported in INSERT statements that contain a clause.

VALUES VALUES
Позволяет использовать один или несколько списков вставляемых значений данных. Introduces the list or lists of data values to be inserted. Для каждого столбца в column_list, если этот параметр указан, или в таблице должно быть одно значение. There must be one data value for each column in column_list, if specified, or in the table. Список значений должен быть заключен в скобки. The value list must be enclosed in parentheses.

Если значения в списке идут в порядке, отличном от порядка следования столбцов в таблице, или не для каждого столбца таблицы определено значение, то необходимо использовать аргумент column_list для явного указания столбца, в котором хранится каждое входное значение. If the values in the Value list are not in the same order as the columns in the table or do not have a value for each column in the table, column_list must be used to explicitly specify the column that stores each incoming value.

Можно использовать конструктор строк Transact-SQL Transact-SQL (также называемый конструктором табличных значений), позволяющий указать несколько строк в одной инструкции INSERT. You can use the Transact-SQL Transact-SQL row constructor (also called a table value constructor) to specify multiple rows in a single INSERT statement. Этот конструктор строк состоит из одного предложения VALUES со списками из нескольких значений, заключенными в круглые скобки и разделенными запятыми. The row constructor consists of a single VALUES clause with multiple value lists enclosed in parentheses and separated by a comma. Дополнительные сведения см. в разделе Конструктор табличных значений (Transact-SQL). For more information, see Table Value Constructor (Transact-SQL).

DEFAULT DEFAULT
Указывает компоненту Компонент Database Engine Database Engine необходимость принудительно загружать значения по умолчанию, определенные для столбца. Forces the Компонент Database Engine Database Engine to load the default value defined for a column. Если для столбца не задано значение по умолчанию и он может содержать значение NULL, вставляется значение NULL. If a default does not exist for the column and the column allows null values, NULL is inserted. В столбцы с типом данных timestamp вставляется следующее значение метки времени. For a column defined with the timestamp data type, the next timestamp value is inserted. Значение DEFAULT недопустимо для столбца идентификаторов. DEFAULT is not valid for an identity column.

expression expression
Константа, переменная или выражение. Is a constant, a variable, or an expression. Выражение не может содержать инструкцию EXECUTE. The expression cannot contain an EXECUTE statement.

При ссылке на типы данных символов Юникода nchar, nvarchar и ntext выражение ‘expression‘ должно начинаться с заглавной буквы ‘N’. When referencing the Unicode character data types nchar, nvarchar, and ntext, ‘expression‘ should be prefixed with the capital letter ‘N’. Если префикс «N» не указан, SQL Server SQL Server выполнит преобразование строки в кодовую страницу, соответствующую параметрам сортировки базы данных или столбца, действующим по умолчанию. If ‘N’ is not specified, SQL Server SQL Server converts the string to the code page that corresponds to the default collation of the database or column. Любые символы, не входящие в эту кодовую страницу, будут утрачены. Any characters not found in this code page are lost.

derived_table derived_table
Любая допустимая инструкция SELECT, возвращающая строки данных, которые загружаются в таблицу. Is any valid SELECT statement that returns rows of data to be loaded into the table. Инструкция SELECT не может содержать обобщенное табличное выражение (CTE). The SELECT statement cannot contain a common table expression (CTE).

execute_statement execute_statement
Любая допустимая инструкция EXECUTE, возвращающая данные с помощью инструкций SELECT или READTEXT. Is any valid EXECUTE statement that returns data with SELECT or READTEXT statements. Дополнительные сведения см. в разделе EXECUTE (Transact-SQL). For more information, see EXECUTE (Transact-SQL).

Параметры RESULT SETS инструкции EXECUTE нельзя указывать в инструкции INSERT…EXEC. The RESULT SETS options of the EXECUTE statement cannot be specified in an INSERT. EXEC statement.

Если аргумент execute_statement используется с инструкцией INSERT, каждый результирующий набор должен быть совместим со столбцами в таблице или списке column_list. If execute_statement is used with INSERT, each result set must be compatible with the columns in the table or in column_list.

Аргумент execute_statement может применяться для выполнения хранимых процедур на том же сервере или на сервере, расположенном удаленно. execute_statement can be used to execute stored procedures on the same server or a remote server. На удаленном сервере выполняется процедура, результирующий набор возвращается на локальный сервер и загружается в таблицу на локальном сервере. The procedure in the remote server is executed, and the result sets are returned to the local server and loaded into the table in the local server. В распределенной транзакции нельзя выполнить инструкцию execute_statement для связанного сервера с замыканием на себя, если при соединении включен режим MARS (множественный активный результирующий набор). In a distributed transaction, execute_statement cannot be issued against a loopback linked server when the connection has multiple active result sets (MARS) enabled.

Если execute_statement возвращает данные с помощью инструкции READTEXT, каждая инструкция READTEXT может возвращать не более 1 МБ (1024 КБ) данных. If execute_statement returns data with the READTEXT statement, each READTEXT statement can return a maximum of 1 MB (1024 KB) of data. execute_statement также может использоваться при работе с расширенными процедурами. execute_statement can also be used with extended procedures. execute_statement вставляет данные, возвращенные главным потоком расширенной процедуры; однако выходные данные из других потоков (кроме главного) не вставляются. execute_statement inserts the data returned by the main thread of the extended procedure; however, output from threads other than the main thread are not inserted.

Возвращающий табличное значение параметр нельзя указывать в качестве объекта инструкции INSERT EXEC, но его можно указать в виде источника в строке INSERT EXEC или в хранимой процедуре. You cannot specify a table-valued parameter as the target of an INSERT EXEC statement; however, it can be specified as a source in the INSERT EXEC string or stored-procedure. Дополнительные сведения см. в статье Использование возвращающих табличные значения параметров (компонент Database Engine). For more information, see Use Table-Valued Parameters (Database Engine).

Указывает, что вставленные в целевую таблицу строки были возвращены предложением OUTPUT инструкции INSERT, UPDATE, DELETE или MERGE с возможной фильтрацией предложением WHERE. Specifies that the rows inserted into the target table are those returned by the OUTPUT clause of an INSERT, UPDATE, DELETE, or MERGE statement, optionally filtered by a WHERE clause. Если используется аргумент , целевая таблица внешней инструкции INSERT должна удовлетворять следующим ограничениям: If is specified, the target of the outer INSERT statement must meet the following restrictions:

Быть базовой таблицей, а не представлением. It must be a base table, not a view.

Не быть удаленной таблицей. It cannot be a remote table.

Не иметь определенных для нее триггеров. It cannot have any triggers defined on it.

Не участвовать в связях «первичный-внешний ключ». It cannot participate in any primary key-foreign key relationships.

Объект не должен участвовать в репликации слиянием или обновляемых подписках для репликации транзакций. It cannot participate in merge replication or updatable subscriptions for transactional replication.

Уровень совместимости базы данных должен быть не ниже 100. The compatibility level of the database must be set to 100 or higher. Дополнительные сведения см. в статье Предложение OUTPUT (Transact-SQL). For more information, see OUTPUT Clause (Transact-SQL).

Список с разделителями-запятыми, указывающий, какие столбцы возвращены предложением OUTPUT для вставки. Is a comma-separated list specifying which columns returned by the OUTPUT clause to insert. Столбцы в должны быть совместимы со столбцами, в которые вставляются значения. The columns in must be compatible with the columns into which values are being inserted. не может ссылаться на агрегатные функции или TEXTPTR. cannot reference aggregate functions or TEXTPTR.

Любые перечисленные в списке SELECT переменные ссылаются на свои исходные значения, независимо от любых изменений, произошедших с ними в . Any variables listed in the SELECT list refer to their original values, regardless of any changes made to them in .

Допустимая инструкция INSERT, UPDATE, DELETE или MERGE, возвращающая изменяемые строки в предложении OUTPUT. Is a valid INSERT, UPDATE, DELETE, or MERGE statement that returns affected rows in an OUTPUT clause. Инструкция не может содержать предложение WITH и использовать удаленные таблицы или секционированные представления в качестве целевых. The statement cannot contain a WITH clause, and cannot target remote tables or partitioned views. Если указаны UPDATE или DELETE, это не могут быть использующие курсор инструкции UPDATE или DELETE. If UPDATE or DELETE is specified, it cannot be a cursor-based UPDATE or DELETE. На исходные строки нельзя ссылаться как на вложенные инструкции DML. Source rows cannot be referenced as nested DML statements.

WHERE WHERE
Любое предложение WHERE, содержащее допустимый критерий поиска , фильтрующее строки, которые возвращены аргументом . Is any WHERE clause containing a valid that filters the rows returned by . Дополнительные сведения см. в разделе Условие поиска (Transact-SQL). For more information, see Search Condition (Transact-SQL). При использовании в этом контексте критерий не должен содержать вложенных запросов, определяемых пользователем скалярных функций, выполняющих доступ к данным, агрегатных функций, TEXTPTR или предикатов полнотекстового поиска. When used in this context, cannot contain subqueries, scalar user-defined functions that perform data access, aggregate functions, TEXTPTR, or full-text search predicates.

DEFAULT VALUES DEFAULT VALUES
Применимо к: с SQL Server 2008 SQL Server 2008 до SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2008 SQL Server 2008 through SQL Server 2020 SQL Server 2020 .

Заполняет новую строку значениями по умолчанию, определенными для каждого столбца. Forces the new row to contain the default values defined for each column.

BULK BULK
Применимо к: с SQL Server 2008 SQL Server 2008 до SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2008 SQL Server 2008 through SQL Server 2020 SQL Server 2020 .

Используется внешними средствами для передачи потока двоичных данных. Used by external tools to upload a binary data stream. Этот параметр не предназначен для использования с такими средствами, как среда SQL Server Management Studio SQL Server Management Studio , SQLCMD, OSQL или программными интерфейсами для доступа к данным, такими как Native Client SQL Server SQL Server . This option is not intended for use with tools such as SQL Server Management Studio SQL Server Management Studio , SQLCMD, OSQL, or data access application programming interfaces such as SQL Server SQL Server Native Client.

FIRE_TRIGGERS FIRE_TRIGGERS
Применимо к: с SQL Server 2008 SQL Server 2008 до SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2008 SQL Server 2008 through SQL Server 2020 SQL Server 2020 .

Указывает, что при передаче потока двоичных данных будут выполняться триггеры INSERT, определенные для целевой таблицы. Specifies that any insert triggers defined on the destination table execute during the binary data stream upload operation. Дополнительные сведения см. в разделе BULK INSERT (Transact-SQL). For more information, see BULK INSERT (Transact-SQL).

CHECK_CONSTRAINTS CHECK_CONSTRAINTS
Применимо к: с SQL Server 2008 SQL Server 2008 до SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2008 SQL Server 2008 through SQL Server 2020 SQL Server 2020 .

Указывает, что при передаче потока двоичных данных будет выполняться проверка всех ограничений целевой таблицы или представления. Specifies that all constraints on the target table or view must be checked during the binary data stream upload operation. Дополнительные сведения см. в разделе BULK INSERT (Transact-SQL). For more information, see BULK INSERT (Transact-SQL).

KEEPNULLS KEEPNULLS
Применимо к: с SQL Server 2008 SQL Server 2008 до SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2008 SQL Server 2008 through SQL Server 2020 SQL Server 2020 .

Указывает, что пустые столбцы во время передачи потока двоичных данных должны сохранить значение NULL. Specifies that empty columns should retain a null value during the binary data stream upload operation. Дополнительные сведения см. в разделе Сохранение значений NULL или использование значений по умолчанию при массовом импорте данных (SQL Server). For more information, see Keep Nulls or Use Default Values During Bulk Import (SQL Server).

KILOBYTES_PER_BATCH = kilobytes_per_batch KILOBYTES_PER_BATCH = kilobytes_per_batch
Определяет приблизительное число килобайт данных в пакете как kilobytes_per_batch. Specifies the approximate number of kilobytes (KB) of data per batch as kilobytes_per_batch. Дополнительные сведения см. в разделе BULK INSERT (Transact-SQL). For more information, see BULK INSERT (Transact-SQL).

ROWS_PER_BATCH =rows_per_batch ROWS_PER_BATCH =rows_per_batch
Применимо к: с SQL Server 2008 SQL Server 2008 до SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2008 SQL Server 2008 through SQL Server 2020 SQL Server 2020 .

Указывает приблизительное число строк в потоке двоичных данных. Indicates the approximate number of rows of data in the binary data stream. Дополнительные сведения см. в разделе BULK INSERT (Transact-SQL). For more information, see BULK INSERT (Transact-SQL).

Если список столбцов отсутствует, то возникает синтаксическая ошибка. A syntax error is raised if a column list is not provided.

Remarks Remarks

Дополнительную информацию о вставке данных в графовые таблицы SQL см. в разделе INSERT (Граф SQL). For information specific to inserting data into SQL graph tables, see INSERT (SQL Graph).

Рекомендации Best Practices

Для возврата в клиентское приложение количества вставленных строк используйте функцию @@ROWCOUNT. Use the @@ROWCOUNT function to return the number of inserted rows to the client application. Дополнительные сведения см. в статье @@ROWCOUNT (Transact-SQL). For more information, see @@ROWCOUNT (Transact-SQL).

Рекомендации по массовому импорту данных Best Practices for Bulk Importing Data

Использование инструкции INSERT INTO…SELECT для массового импорта данных с минимальным протоколированием Using INSERT INTO. SELECT to Bulk Import Data with Minimal Logging

Инструкция INSERT INTO SELECT FROM может эффективно перенести большое количество строк из одной таблицы (например, промежуточной) в другую таблицу с минимальным протоколированием. You can use INSERT INTO SELECT FROM to efficiently transfer a large number of rows from one table, such as a staging table, to another table with minimal logging. Минимальное протоколирование может повысить производительность выполнения инструкции и снизить вероятность того, что во время операции будет заполнен весь журнал транзакций. Minimal logging can improve the performance of the statement and reduce the possibility of the operation filling the available transaction log space during the transaction.

Для минимального протоколирования этой инструкции необходимо выполнение следующих требований. Minimal logging for this statement has the following requirements:

Модель восстановления базы данных настроена на простое или неполное протоколирование. The recovery model of the database is set to simple or bulk-logged.

Целевой таблицей является пустая или непустая куча. The target table is an empty or nonempty heap.

Целевая таблица не используется в репликации. The target table is not used in replication.

Для целевой таблицы указана подсказка TABLOCK. The TABLOCK hint is specified for the target table.

Для строк, которые вставляются в кучу в результате действия вставки в инструкции MERGE, также может применяться минимальное протоколирование. Rows that are inserted into a heap as the result of an insert action in a MERGE statement may also be minimally logged.

В отличие от инструкции BULK INSERT, которая удерживает менее строгую блокировку массового обновления, инструкция INSERT INTO…SELECT с указанием TABLOCK удерживает монопольную блокировку (X) таблицы. Unlike the BULK INSERT statement, which holds a less restrictive Bulk Update lock, INSERT INTO. SELECT with the TABLOCK hint holds an exclusive (X) lock on the table. Это означает, что отсутствует возможность вставки строк с помощью параллельных операций вставки. This means that you cannot insert rows using parallel insert operations.

Использование предложений OPENROWSET и BULK для массового импорта данных Using OPENROWSET and BULK to Bulk Import Data

Функция OPENROWSET может принимать следующие табличные подсказки, обеспечивающие оптимизацию массовой загрузки с инструкцией INSERT. The OPENROWSET function can accept the following table hints, which provide bulk-load optimizations with the INSERT statement:

Использование подсказки TABLOCK может свести к минимуму число записей в журнале для операции вставки. The TABLOCK hint can minimize the number of log records for the insert operation. Для базы данных должна быть установлена простая модель восстановления или модель восстановления с неполным протоколированием. Кроме того, целевая таблица не может использоваться в репликации. The recovery model of the database must be set to simple or bulk-logged and the target table cannot be used in replication. Дополнительные сведения см. в разделе Предварительные условия для минимального протоколирования массового импорта данных. For more information, see Prerequisites for Minimal Logging in Bulk Import.

Проверку ограничений FOREIGN KEY и CHECK можно временно отключить с помощью подсказки IGNORE_CONSTRAINTS. The IGNORE_CONSTRAINTS hint can temporarily disable FOREIGN KEY and CHECK constraint checking.

Выполнение триггеров можно временно отключить с помощью подсказки IGNORE_TRIGGERS. The IGNORE_TRIGGERS hint can temporarily disable trigger execution.

Указание KEEPDEFAULTS позволяет вставить установленное по умолчанию значение столбца таблицы, если таковое имеется, вместо значения NULL, применяемого в случае, когда запись данных не содержит значения для этого столбца. The KEEPDEFAULTS hint allows the insertion of a table column’s default value, if any, instead of NULL when the data record lacks a value for the column.

Подсказка KEEPIDENTITY позволяет использовать значения идентификаторов в файле импортированных данных для столбца идентификаторов в целевой таблице. The KEEPIDENTITY hint allows the identity values in the imported data file to be used for the identity column in the target table.

Эти оптимизации похожи на оптимизации, доступные для команды BULK INSERT. These optimizations are similar to those available with the BULK INSERT command. Дополнительные сведения см. в разделе Табличные указания (Transact-SQL). For more information, see Table Hints (Transact-SQL).

Типы данных Data Types

При вставке строк необходимо учитывать поведение следующих типов данных: When you insert rows, consider the following data type behavior:

Если значение загружается в столбцы с типом данных char, varchar и varbinary, то заполнение или усечение конечных пробелов (пробелы для char и varchar, нули для varbinary) определяется параметром SET ANSI_PADDING, определенным для столбца при создании таблицы. If a value is being loaded into columns with a char, varchar, or varbinary data type, the padding or truncation of trailing blanks (spaces for char and varchar, zeros for varbinary) is determined by the SET ANSI_PADDING setting defined for the column when the table was created. Дополнительные сведения см. в разделе SET ANSI_PADDING (Transact-SQL). For more information, see SET ANSI_PADDING (Transact-SQL).

В следующей таблице показаны операции по умолчанию для параметра SET ANSI_PADDING, установленного в значение OFF. The following table shows the default operation for SET ANSI_PADDING OFF.

Тип данных Data type Стандартная операция Default operation
charchar Заполнение значения пробелами до заданной ширины столбца. Pad value with spaces to the defined width of column.
varcharvarchar Удаление конечных пробелов до последнего непробельного символа или до одного пробела, если строка состоит только из пробелов. Remove trailing spaces to the last non-space character or to a single-space character for strings made up of only spaces.
varbinaryvarbinary Удаление конечных нулей. Remove trailing zeros.

Если пустая строка (‘ ‘) загружена в столбец с типом данных varchar или text, то операцией по умолчанию будет загрузка строки нулевой длины. If an empty string (‘ ‘) is loaded into a column with a varchar or text data type, the default operation is to load a zero-length string.

Вставка значения NULL в столбец text или image не приводит ни к созданию допустимого текстового указателя, ни к предварительному распределению 8-килобайтной текстовой страницы. Inserting a null value into a text or image column does not create a valid text pointer, nor does it preallocate an 8-KB text page.

Столбцы, созданные с типом данных uniqueidentifier, содержат двоичные 16-байтные значения специального формата. Columns created with the uniqueidentifier data type store specially formatted 16-byte binary values. В отличие от столбцов идентификаторов Компонент Database Engine Database Engine не создает автоматически значения для столбцов с типом данных uniqueidentifier. Unlike with >Компонент Database Engine Database Engine does not automatically generate values for columns with the uniqueidentifier data type. При вставке переменные с типом данных uniqueidentifier и константы строк в форме xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (36 символов, включая дефисы, где x является шестнадцатеричной цифрой в диапазоне 0–9 или a–f) могут быть использованы для столбцов uniqueidentifier. During an insert operation, variables with a data type of uniqueidentifier and string constants in the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (36 characters including hyphens, where x is a hexadecimal digit in the range 0-9 or a-f) can be used for uniqueidentifier columns. Например, 6F9619FF-8B86-D011-B42D-00C04FC964FF является допустимым значением переменной или столбца uniqueidentifier. For example, 6F9619FF-8B86-D011-B42D-00C04FC964FF is a valid value for a uniqueidentifier variable or column. Используйте функцию NEWID() для получения идентификатора GUID. Use the NEWID() function to obtain a globally unique ID (GUID).

Вставка значений в столбцы определяемого пользователем типа Inserting Values into User-Defined Type Columns

Вставлять значения в столбцы определяемого пользователем типа можно следующими способами. You can insert values in user-defined type columns by:

Предоставление значения определяемого пользователем типа. Supplying a value of the user-defined type.

Предоставление значения типа системных данных SQL Server SQL Server происходит, если определяемый пользователем тип поддерживает явное или неявное преобразование из этого типа. Supplying a value in a SQL Server SQL Server system data type, as long as the user-defined type supports implicit or explicit conversion from that type. В следующем примере показано, как вставляются значения из столбца определяемого пользователем типа Point путем явного преобразования из строки. The following example shows how to insert a value in a column of user-defined type Point , by explicitly converting from a string.

Двоичное значение также может предоставляться без выполнения явного преобразования, так как все определяемые пользователем типы могут быть неявно преобразованы из двоичного. A binary value can also be supplied without performing explicit conversion, because all user-defined types are implicitly convertible from binary.

Вызов определяемой пользователем функции, которая возвращает значение определяемого пользователем типа. Calling a user-defined function that returns a value of the user-defined type. В следующих примерах используется определяемая пользователем функция CreateNewPoint() для создания новых значений определяемого пользователем типа Point и вставки значения в таблицу Cities . The following example uses a user-defined function CreateNewPoint() to create a new value of user-defined type Point and insert the value into the Cities table.

Обработка ошибок Error Handling

Для инструкции INSERT можно реализовать обработку ошибок, указав инструкцию в конструкции TRY…CATCH. You can implement error handling for the INSERT statement by specifying the statement in a TRY. CATCH construct.

Если инструкция INSERT нарушает ограничение или правило, либо в ней присутствует значение, несовместимое с типом данных столбца, то при выполнении инструкции происходит сбой и отображается сообщение об ошибке. If an INSERT statement violates a constraint or rule, or if it has a value incompatible with the data type of the column, the statement fails and an error message is returned.

Если инструкция INSERT загружает несколько строк с помощью инструкции SELECT или EXECUTE, то любые нарушения правил или ограничений, возникающие из-за загружаемых значений, приводят к остановке выполнения инструкции, и ни одна из строк не будет загружена. If INSERT is loading multiple rows with SELECT or EXECUTE, any violation of a rule or constraint that occurs from the values being loaded causes the statement to be stopped, and no rows are loaded.

Если при выполнении инструкции INSERT возникает арифметическая ошибка (переполнение, деление на ноль или ошибка домена), компонент Компонент Database Engine Database Engine обрабатывает эти ошибки так же, как если бы параметру SET ARITHABORT было присвоено значение ON. When an INSERT statement encounters an arithmetic error (overflow, div >Компонент Database Engine Database Engine handles these errors as if SET ARITHABORT is set to ON. Выполнение пакета прекращается и выводится сообщение об ошибке. The batch is stopped, and an error message is returned. Во время оценки выражения, когда параметры SET ARITHABORT и SET ANSI_WARNINGS установлены в значение OFF, если в инструкции INSERT, DELETE или UPDATE происходит арифметическая ошибка переполнения, деления на ноль или ошибка области определения, SQL Server SQL Server вставляет или обновляет значение NULL. During expression evaluation when SET ARITHABORT and SET ANSI_WARNINGS are OFF, if an INSERT, DELETE or UPDATE statement encounters an arithmetic error, overflow, div >SQL Server SQL Server inserts or updates a NULL value. Если целевой столбец не пустой, вставка или обновление не осуществляются, и пользователь получает ошибку. If the target column is not nullable, the insert or update action fails and the user receives an error.

Совместимость Interoperability

Если триггер INSTEAD OF определен в операциях INSERT для таблицы или представления, то триггер выполняется вместо инструкции INSERT. When an INSTEAD OF trigger is defined on INSERT actions against a table or view, the trigger executes instead of the INSERT statement. Дополнительные сведения о триггерах INSTEAD OF см. в разделе CREATE TRIGGER (Transact-SQL). For more information about INSTEAD OF triggers, see CREATE TRIGGER (Transact-SQL).

Ограничения Limitations and Restrictions

Если во время вставки значений в удаленные таблицы указаны не все значения для всех столбцов, то необходимо указать столбцы, в которые вставляются заданные значения. When you insert values into remote tables and not all values for all columns are specified, you must identify the columns to which the specified values are to be inserted.

При использовании выражения TOP в инструкции INSERT строки, на которые имеются ссылки, не упорядочиваются, а предложение ORDER BY не может быть прямо указано в этих инструкциях. When TOP is used with INSERT the referenced rows are not arranged in any order and the ORDER BY clause can not be directly specified in this statements. Если для вставки строк в значимом хронологическом порядке необходимо использовать предложение TOP, вместе с ним в инструкции подзапроса выборки следует использовать предложение ORDER BY. If you need to use TOP to insert rows in a meaningful chronological order, you must use TOP together with an ORDER BY clause that is specified in a subselect statement. См. подраздел «Примеры» далее в этом разделе. See the Examples section that follows in this topic.

Запросы INSERT, которые используют SELECT с ORDER BY для заполнения строк, гарантируют способ вычисления значений идентификатора, но не порядок вставки строк. INSERT queries that use SELECT with ORDER BY to populate rows guarantees how identity values are computed but not the order in which the rows are inserted.

В Parallel Data Warehouse предложение ORDER BY недопустимо в инструкциях VIEWS, CREATE TABLE AS SELECT, INSERT SELECT, встраиваемых функциях, производных таблицах, подзапросах и обобщенных табличных выражениях, если также не указать TOP. In Parallel Data Warehouse, the ORDER BY clause is invalid in VIEWS, CREATE TABLE AS SELECT, INSERT SELECT, inline functions, derived tables, subqueries and common table expressions, unless TOP is also specified.

Режим ведения журнала Logging Behavior

Инструкция INSERT всегда полностью регистрируется в журнале, кроме случаев использования функции OPENROWSET с ключевым словом BULK или выполнения инструкции INSERT INTO SELECT FROM . The INSERT statement is always fully logged except when using the OPENROWSET function with the BULK keyword or when using INSERT INTO SELECT FROM . Для этих операций возможно минимальное протоколирование. These operations can be minimally logged. Дополнительные сведения см. в подразделе «Рекомендации по массовой загрузке данных» этого раздела. For more information, see the section «Best Practices for Bulk Loading Data» earlier in this topic.

безопасность Security

При соединении со связанным сервером отправляющий сервер указывает имя входа и пароль для подключения к принимающему серверу от его имени. During a linked server connection, the sending server provides a login name and password to connect to the receiving server on its behalf. Для работы этого соединения необходимо создать сопоставление имен входа между связанными серверами вызовом хранимой процедуры sp_addlinkedsrvlogin. For this connection to work, you must create a login mapping between the linked servers by using sp_addlinkedsrvlogin.

При использовании функции OPENROWSET(BULK…) важно понимать, каким образом SQL Server SQL Server обрабатывает олицетворение. When you use OPENROWSET(BULK. ), it is important to understand how SQL Server SQL Server handles impersonation. Дополнительные сведения см. в главе «Вопросы безопасности» в разделе Массовый импорт данных при помощи инструкции BULK INSERT или OPENROWSET(BULK. ) (SQL Server). For more information, see «Security Considerations» in Import Bulk Data by Using BULK INSERT or OPENROWSET(BULK. ) (SQL Server).

Разрешения Permissions

Требуется разрешение INSERT на целевую таблицу. INSERT permission is required on the target table.

Разрешения INSERT назначаются по умолчанию членам предопределенной роли сервера sysadmin, предопределенных ролей базы данных db_owner и db_datawriter, а также владельцу таблицы. INSERT permissions default to members of the sysadmin fixed server role, the db_owner and db_datawriter fixed database roles, and the table owner. Члены ролей sysadmin, db_owner и db_securityadmin, а также владелец таблицы могут передавать разрешения другим пользователям. Members of the sysadmin, db_owner, and the db_securityadmin roles, and the table owner can transfer permissions to other users.

Чтобы выполнить инструкцию INSERT с параметром BULK функции OPENROWSET, необходимо быть членом предопределенной роли сервера sysadmin или bulkadmin. To execute INSERT with the OPENROWSET function BULK option, you must be a member of the sysadmin fixed server role or of the bulkadmin fixed server role.

Примеры Examples

Категория Category Используемые элементы синтаксиса Featured syntax elements
Основной синтаксис Basic syntax INSERT • конструктор табличных значений INSERT • table value constructor
Обработка значений столбца Handling column values IDENTITY • NEWID • значения по умолчанию • определяемые пользователем типы IDENTITY • NEWID • default values • user-defined types
Вставка данных из других таблиц Inserting data from other tables INSERT…SELECT • INSERT…EXECUTE • WITH обобщенное табличное выражение • TOP• OFFSET FETCH INSERT. SELECT • INSERT. EXECUTE • WITH common table expression • TOP • OFFSET FETCH
Указание целевых объектов, отличных от стандартных таблиц Specifying target objects other than standard tables Представления • табличные переменные Views • table variables
Вставка строк в удаленную таблицу Inserting rows into a remote table Связанный сервер • OPENQUERY, функция набора строк • OPENDATASOURCE, функция набора строк Linked server • OPENQUERY rowset function • OPENDATASOURCE rowset function
Массовая загрузка данных из таблиц или файлов данных Bulk loading data from tables or data files INSERT…SELECT • OPENROWSET, функция INSERT. SELECT • OPENROWSET function
Переопределение поведения по умолчанию для оптимизатора запросов с помощью указаний Overriding the default behavior of the query optimizer by using hints Табличные указания Table hints
Сбор результатов инструкции INSERT Capturing the results of the INSERT statement OUTPUT, предложение OUTPUT clause

Базовый синтаксис Basic Syntax

В примерах в этом разделе описывается базовая функциональность инструкции INSERT с помощью минимального необходимого синтаксиса. Examples in this section demonstrate the basic functionality of the INSERT statement using the minimum required syntax.

A. A. Вставка одной строки данных Inserting a single row of data

В следующем примере показана вставка одной строки в таблицу Production.UnitMeasure базы данных AdventureWorks2012 AdventureWorks2012 . The following example inserts one row into the Production.UnitMeasure table in the AdventureWorks2012 AdventureWorks2012 database. В этой таблице содержатся столбцы UnitMeasureCode , Name и ModifiedDate . The columns in this table are UnitMeasureCode , Name , and ModifiedDate . Так как значения для всех столбцов предоставлены и перечислены в том же порядке, что и столбцы в таблице, то не нужно указывать имена столбцов в списке столбцов . Because values for all columns are supplied and are listed in the same order as the columns in the table, the column names do not have to be specified in the column list .

Б. B. Вставка нескольких строк данных Inserting multiple rows of data

В следующем примере используется конструктор значений таблицы для вставки трех строк в таблицу Production.UnitMeasure базы данных AdventureWorks2012 AdventureWorks2012 в единственной инструкции INSERT. The following example uses the table value constructor to insert three rows into the Production.UnitMeasure table in the AdventureWorks2012 AdventureWorks2012 database in a single INSERT statement. Так как значения для всех столбцов предоставлены и перечислены в том же порядке, что и столбцы в таблице, то не нужно в параметре указывать имена столбцов. Because values for all columns are supplied and are listed in the same order as the columns in the table, the column names do not have to be specified in the column list.

В. C. Вставка данных в порядке, отличном от порядка столбцов таблицы Inserting data that is not in the same order as the table columns

В следующем примере используется список столбцов для явного указания значений, которые будут вставляться в каждый столбец. The following example uses a column list to explicitly specify the values that are inserted into each column. Порядок следования столбцов в таблице Production.UnitMeasure базы данных AdventureWorks2012 AdventureWorks2012 является следующим: UnitMeasureCode , Name , ModifiedDate . Но в column_list столбцы перечислены в ином порядке. The column order in the Production.UnitMeasure table in the AdventureWorks2012 AdventureWorks2012 database is UnitMeasureCode , Name , ModifiedDate ; however, the columns are not listed in that order in column_list.

Обработка значений столбца Handling Column Values

Примеры в этом разделе описывают методы вставки значений в столбцы, которые определяются с помощью свойства IDENTITY, значения DEFAULT или с помощью типов данных, таких как uniqueidentifer или столбцов определяемого пользователем типа. Examples in this section demonstrate methods of inserting values into columns that are defined with an IDENTITY property, DEFAULT value, or are defined with data types such as uniqueidentifer or user-defined type columns.

Г. D. Вставка данных в таблицу со столбцами, имеющими значение по умолчанию Inserting data into a table with columns that have default values

В следующем примере показана вставка строк в таблицу со столбцами, для которых автоматически создается значение или которые имеют значение по умолчанию. The following example shows inserting rows into a table with columns that automatically generate a value or have a default value. Column_1 — это вычисляемый столбец, который автоматически создает значение, объединяя строку со значением, вставленным в столбец column_2 . Column_1 is a computed column that automatically generates a value by concatenating a string with the value inserted into column_2 . Столбец Column_2 определен с ограничением по умолчанию. Column_2 is defined with a default constraint. Если для этого столбца не указано значение, используется значение по умолчанию. If a value is not specified for this column, the default value is used. Столбец Column_3 имеет тип данных rowversion, который автоматически создает уникальное, последовательно увеличиваемое двоичное число. Column_3 is defined with the rowversion data type, which automatically generates a unique, incrementing binary number. Столбец Column_4 не формирует значения автоматически. Column_4 does not automatically generate a value. Если значение для этого столбца отсутствует, то вставляется значение NULL. When a value for this column is not specified, NULL is inserted. Инструкция INSERT вставляет строки, которые содержат значения для некоторых столбцов, но не для всех. The INSERT statements insert rows that contain values for some of the columns but not all. В последней инструкции INSERT столбцы не указаны, и поэтому вставляются только значения по умолчанию с помощью предложения DEFAULT VALUES. In the last INSERT statement, no columns are specified and only the default values are inserted by using the DEFAULT VALUES clause.

Д. E. Вставка данных в таблицу со столбцом идентификаторов Inserting data into a table with an identity column

В следующем примере показаны различные методы вставки данных в столбец идентификаторов. The following example shows different methods of inserting data into an identity column. Первые две инструкции INSERT позволяют формировать значения идентификаторов для новых строк. The first two INSERT statements allow identity values to be generated for the new rows. Третья инструкция INSERT переопределяет свойство IDENTITY столбца с помощью инструкции SET IDENTITY_INSERT и вставляет явно заданное значение в столбец идентификаторов. The third INSERT statement overrides the IDENTITY property for the column with the SET IDENTITY_INSERT statement and inserts an explicit value into the identity column.

Е. F. Вставка данных в столбец типа uniqueidentifier с помощью функции NEWID() Inserting data into a uniqueidentifier column by using NEWID()

В следующем примере функция NEWID() вызывается для вставки идентификатора GUID в столбец column_2 . The following example uses the NEWID() function to obtain a GUID for column_2 . В отличие от столбцов идентификаторов, компонент Компонент Database Engine Database Engine не создает автоматически значения для столбцов с типом данных uniqueidentifier, как показано во второй инструкции INSERT . Unlike for >Компонент Database Engine Database Engine does not automatically generate values for columns with the uniqueidentifier data type, as shown by the second INSERT statement.

Ж. G. Вставка данных в столбцы определяемого пользователем типа Inserting data into user-defined type columns

Следующие инструкции Transact-SQL Transact-SQL вставляют три строки в столбец PointValue таблицы Points . The following Transact-SQL Transact-SQL statements insert three rows into the PointValue column of the Points table. Этот столбец имеет определяемый пользователем тип данных CLR. This column uses a CLR user-defined type (UDT). Тип данных Point состоит из целочисленных значений X и Y, которые представлены как свойства определяемого пользователем типа. The Point data type consists of X and Y integer values that are exposed as properties of the UDT. Необходимо привести разделяемые запятой значения X и Y к типу Point с помощью функции CAST или CONVERT. You must use either the CAST or CONVERT function to cast the comma-delimited X and Y values to the Point type. Первые две инструкции используют функцию CONVERT для преобразования строкового значения в тип Point , а третья инструкция использует функцию CAST. The first two statements use the CONVERT function to convert a string value to the Point type, and the third statement uses the CAST function. Дополнительные сведения см. в разделе Работа с данными определяемого пользователем типа. For more information, see Manipulating UDT Data.

Вставка данных из других таблиц Inserting Data from Other Tables

В примерах этого раздела показаны методы вставки строк из одной таблицы в другую. Examples in this section demonstrate methods of inserting rows from one table into another table.

З. H. Вставка данных из других таблиц с помощью параметров SELECT и EXECUTE Using the SELECT and EXECUTE options to insert data from other tables

В следующем примере описана вставка данных из одной таблицы в другую с помощью инструкций INSERT…SELECT и INSERT…EXECUTE. The following example shows how to insert data from one table into another table by using INSERT. SELECT or INSERT. EXECUTE. Каждый метод основан на многотабличной инструкции SELECT, содержащей выражение и литеральное значение в списке столбцов. Each is based on a multi-table SELECT statement that includes an expression and a literal value in the column list.

В первой инструкции INSERT используется инструкция SELECT для получения данных из исходных таблиц ( Employee , SalesPerson и Person ) в базе данных AdventureWorks2012 AdventureWorks2012 и сохранения результирующего набора в таблице EmployeeSales . The first INSERT statement uses a SELECT statement to derive the data from the source tables ( Employee , SalesPerson , and Person ) in the AdventureWorks2012 AdventureWorks2012 database and store the result set in the EmployeeSales table. Вторая инструкция INSERT с помощью предложения EXECUTE вызывает хранимую процедуру, содержащую инструкцию SELECT, а третья инструкция INSERT с помощью предложения EXECUTE ссылается на инструкцию SELECT как на символьную строку. The second INSERT statement uses the EXECUTE clause to call a stored procedure that contains the SELECT statement, and the third INSERT uses the EXECUTE clause to reference the SELECT statement as a literal string.

И. I. Использование обобщенного табличного выражения WITH для определения вставляемых данных Using WITH common table expression to define the data inserted

В следующем примере создается таблица NewEmployee в базе данных AdventureWorks2012 AdventureWorks2012 . The following example creates the NewEmployee table in the AdventureWorks2012 AdventureWorks2012 database. Обобщенное табличное выражение ( EmployeeTemp ) определяет строки из одной или нескольких таблиц, которые вставляются в таблицу NewEmployee . A common table expression ( EmployeeTemp ) defines the rows from one or more tables to be inserted into the NewEmployee table. Инструкция INSERT ссылается на столбцы в обобщенном табличном выражении. The INSERT statement references the columns in the common table expression.

К. J. Использование TOP для ограничения данных, вставляемых из исходной таблицы Using TOP to limit the data inserted from the source table

В следующем примере создается таблица EmployeeSales и выполняется вставка данных о продажах за текущий год для пяти первых случайно выбранных сотрудников из таблицы HumanResources.Employee в базу данных AdventureWorks2012 AdventureWorks2012 . The following example creates the table EmployeeSales and inserts the name and year-to-date sales data for the top 5 random employees from the table HumanResources.Employee in the AdventureWorks2012 AdventureWorks2012 database. Инструкция INSERT выбирает любые пять строк из строк, возвращенных инструкцией SELECT . The INSERT statement chooses any 5 rows returned by the SELECT statement. Предложение OUTPUT отображает строки, вставляемые в таблицу EmployeeSales . The OUTPUT clause displays the rows that are inserted into the EmployeeSales table. Обратите внимание, что предложение ORDER BY в инструкции SELECT не используется для определения 5 наиболее успешных сотрудников. Notice that the ORDER BY clause in the SELECT statement is not used to determine the top 5 employees.

Если для вставки строк в значимом хронологическом порядке решено использовать предложение TOP, вместе с ним в инструкции подзапроса выборки следует использовать предложение ORDER BY, как показано в следующем примере. If you have to use TOP to insert rows in a meaningful chronological order, you must use TOP together with ORDER BY in a subselect statement as shown in the following example. Предложение OUTPUT отображает строки, вставляемые в таблицу EmployeeSales . The OUTPUT clause displays the rows that are inserted into the EmployeeSales table. Обратите внимание, что вставка данных 5 наиболее успешных сотрудников выполняется на основе результатов предложения ORDER BY, а не случайных строк. Notice that the top 5 employees are now inserted based on the results of the ORDER BY clause instead of random rows.

Указание целевых объектов, отличных от стандартных таблиц Specifying Target Objects Other Than Standard Tables

В примерах этого раздела показаны методы вставки строк с указанием представления или табличной переменной. Examples in this section demonstrate how to insert rows by specifying a view or table variable.

Л. K. Вставка данных с указанием представления Inserting data by specifying a view

В следующем примере в качестве целевого объекта указано имя представления; новая строка вставляется в базовую таблицу. The following example specifies a view name as the target object; however, the new row is inserted in the underlying base table. Порядок следования значений в инструкции INSERT должен совпадать с порядком следования столбцов в представлении. The order of the values in the INSERT statement must match the column order of the view. Дополнительные сведения см. в разделе Изменение данных через представление. For more information, see Modify Data Through a View.

М. L. Вставка данных в табличную переменную Inserting data into a table variable

В следующем примере задается переменная таблицы в качестве целевого объекта в базе данных AdventureWorks2012 AdventureWorks2012 . The following example specifies a table variable as the target object in the AdventureWorks2012 AdventureWorks2012 database.

Вставка строк в удаленную таблицу Inserting Rows into a Remote Table

В примерах в этом разделе описаны способы вставки в удаленную целевую таблицу с использованием в качестве ссылки на удаленную таблицу связанного сервера или функции, возвращающей набор строк. Examples in this section demonstrate how to insert rows into a remote target table by using a linked server or a rowset function to reference the remote table.

Н. M. Вставка данных в удаленную таблицу с использованием связанного сервера Inserting data into a remote table by using a linked server

В следующем примере в удаленную таблицу вставляются строки. The following example inserts rows into a remote table. Этот пример начинается с создания ссылки на удаленный источник данных с помощью хранимой процедуры sp_addlinkedserver. The example begins by creating a link to the remote data source by using sp_addlinkedserver. Имя связанного сервера, MyLinkServer , затем определяется как часть четырехчастного имени объекта в форме server.catalog.schema.object. The linked server name, MyLinkServer , is then specified as part of the four-part object name in the form server.catalog.schema.object.

Применимо к: с SQL Server 2008 SQL Server 2008 до SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2008 SQL Server 2008 through SQL Server 2020 SQL Server 2020 .

О. N. Вставка данных в удаленную таблицу с помощью функции OPENQUERY Inserting data into a remote table by using the OPENQUERY function

В следующем примере выполняется вставка строки в удаленную таблицу с помощью вызова функции OPENQUERY, возвращающей набор строк. The following example inserts a row into a remote table by specifying the OPENQUERY rowset function. В этом примере используется имя связанного сервера, созданного в предыдущем примере. The linked server name created in the previous example is used in this example.

Применимо к: с SQL Server 2008 SQL Server 2008 до SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2008 SQL Server 2008 through SQL Server 2020 SQL Server 2020 .

П. O. Вставка данных в удаленную таблицу с помощью функции OPENDATASOURCE Inserting data into a remote table by using the OPENDATASOURCE function

В следующем примере выполняется вставка строки в удаленную таблицу с помощью вызова функции OPENDATASOURCE, возвращающей набор строк. The following example inserts a row into a remote table by specifying the OPENDATASOURCE rowset function. Определите допустимое имя сервера для источника данных, используя формат server_name или server_name\instance_name. Specify a valid server name for the data source by using the format server_name or server_name\instance_name.

Применимо к: с SQL Server 2008 SQL Server 2008 до SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2008 SQL Server 2008 through SQL Server 2020 SQL Server 2020 .

Т. P. Вставка во внешнюю таблицу, созданную с помощью PolyBase Inserting into an external table created using PolyBase

Вы можете экспортировать данные из SQL Server в службу хранилища Azure или Hadoop. Export data from SQL Server to Hadoop or Azure Storage. Для этого сначала необходимо создать внешнюю таблицу, которая указывает на целевой файл или каталог. First, create an external table that points to the destination file or directory. Затем используйте инструкцию INSERT INTO, чтобы экспортировать данные из локальной таблицы SQL Server во внешний источник данных. Then, use INSERT INTO to export data from a local SQL Server table to an external data source. При выполнении инструкции INSERT INTO создается целевой файл или каталог (если его не существует), а результаты выполнения инструкции SELECT экспортируются в указанное расположение в заданном формате. The INSERT INTO statement creates the destination file or directory if it does not exist and the results of the SELECT statement are exported to the specified location in the specified file format. Дополнительные сведения см. в разделе Приступая к работе с PolyBase. For more information, see Get started with PolyBase.

Применимо к: SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2020 SQL Server 2020 .

Массовая загрузка данных из таблиц или файлов данных Bulk Loading Data from Tables or Data Files

В примерах этого раздела показано два метода массовой загрузки данных в таблицу с помощью инструкции INSERT. Examples in this section demonstrate two methods to bulk load data into a table by using the INSERT statement.

У. Q. Вставка данных в кучу с минимальным протоколированием Inserting data into a heap with minimal logging

В следующем примере создается таблица (куча), в которую вставляются данные из другой таблицы с минимальным протоколированием. The following example creates a new table (a heap) and inserts data from another table into it using minimal logging. В примере предполагается, что для базы данных AdventureWorks2012 выбрана модель восстановления FULL. The example assumes that the recovery model of the AdventureWorks2012 database is set to FULL. Чтобы убедиться, что применяется минимальное протоколирование, модель восстановления базы данных AdventureWorks2012 перед вставкой строк устанавливается в значение BULK_LOGGED, а после выполнения инструкции INSERT INTO… SELECT возвращается в значение FULL. To ensure minimal logging is used, the recovery model of the AdventureWorks2012 database is set to BULK_LOGGED before rows are inserted and reset to FULL after the INSERT INTO. SELECT statement. Кроме того, для целевой таблицы Sales.SalesHistory указывается подсказка TABLOCK. In addition, the TABLOCK hint is specified for the target table Sales.SalesHistory . Это обеспечивает минимальное использование журнала транзакций инструкцией и ее эффективное выполнение. This ensures that the statement uses minimal space in the transaction log and performs efficiently.

Ф. R. Использование функции OPENROWSET с параметром BULK для массовой загрузки данных а таблицу Using the OPENROWSET function with BULK to bulk load data into a table

В следующем примере выполняется вставка строки в таблицу из файла данных вызовом функции OPENQUERY. The following example inserts rows from a data file into a table by specifying the OPENROWSET function. Для оптимизации производительности указывается табличная подсказка IGNORE_TRIGGERS. The IGNORE_TRIGGERS table hint is specified for performance optimization. Дополнительные примеры см. в разделе Массовый импорт данных при помощи инструкции BULK INSERT или OPENROWSET(BULK. ) (SQL Server). For more examples, see Import Bulk Data by Using BULK INSERT or OPENROWSET(BULK. ) (SQL Server).

Применимо к: с SQL Server 2008 SQL Server 2008 до SQL Server 2020 SQL Server 2020 . Applies to: SQL Server 2008 SQL Server 2008 through SQL Server 2020 SQL Server 2020 .

Переопределение поведения по умолчанию для оптимизатора запросов с помощью указаний Overriding the Default Behavior of the Query Optimizer by Using Hints

Примеры в этом разделе описывают использование табличных указаний для временного переопределения поведения оптимизатора запросов при обработке инструкции INSERT. Examples in this section demonstrate how to use table hints to temporarily override the default behavior of the query optimizer when processing the INSERT statement.

Поскольку оптимизатор запросов SQL Server SQL Server обычно выбирает наилучший план выполнения запроса, подсказки рекомендуется использовать только опытным разработчикам и администраторам баз данных в качестве последнего средства. Because the SQL Server SQL Server query optimizer typically selects the best execution plan for a query, we recommend that hints be used only as a last resort by experienced developers and database administrators.

Х. S. Использование подсказки TABLOCK для указания метода блокировки Using the TABLOCK hint to specify a locking method

В следующем примере показано, как монопольная блокировка (Х) применяется к таблице Production.Location и сохраняется до завершения инструкции UPDATE. The following example specifies that an exclusive (X) lock is taken on the Production.Location table and is held until the end of the INSERT statement.

Применимо к: SQL Server SQL Server , База данных SQL SQL Database . Applies to: SQL Server SQL Server , База данных SQL SQL Database .

Сбор результатов инструкции INSERT Capturing the Results of the INSERT Statement

Примеры в этом разделе описывают использование предложения OUTPUT для возврата данных для всех строк, изменившихся в результате выполнения инструкции INSERT, либо выражений на основе этих данных. Examples in this section demonstrate how to use the OUTPUT Clause to return information from, or expressions based on, each row affected by an INSERT statement. Эти результаты могут быть возвращены приложению, например для вывода подтверждающих сообщений, архивирования и т. п. These results can be returned to the processing application for use in such things as confirmation messages, archiving, and other such application requirements.

T. T. Использование предложения OUTPUT с инструкцией INSERT Using OUTPUT with an INSERT statement

В следующем примере производится вставка строки в таблицу ScrapReason , а затем при помощи предложения OUTPUT результаты выполнения инструкции возвращаются в табличную переменную @MyTableVar . The following example inserts a row into the ScrapReason table and uses the OUTPUT clause to return the results of the statement to the @MyTableVar table variable. Так как столбец ScrapReasonID определен с помощью свойства IDENTITY , то значение для этого столбца не указано в инструкции INSERT . Because the ScrapReasonID column is defined with an IDENTITY property, a value is not specified in the INSERT statement for that column. Однако следует заметить, что значение, созданное компонентом Компонент Database Engine Database Engine для этого столбца, возвращается в предложении OUTPUT в столбец INSERTED.ScrapReasonID . However, note that the value generated by the Компонент Database Engine Database Engine for that column is returned in the OUTPUT clause in the INSERTED.ScrapReasonID column.

Ф. U. Применение предложения OUTPUT со столбцами идентификаторов и вычисляемыми столбцами Using OUTPUT with identity and computed columns

В следующем примере создается таблица EmployeeSales , а затем в нее с помощью инструкции INSERT вставляется несколько строк, получаемых инструкцией SELECT из исходных таблиц. The following example creates the EmployeeSales table and then inserts several rows into it using an INSERT statement with a SELECT statement to retrieve data from source tables. Таблица EmployeeSales содержит столбец идентификаторов ( EmployeeID ) и вычисляемый столбец ( ProjectedSales ). The EmployeeSales table contains an identity column ( EmployeeID ) and a computed column ( ProjectedSales ). Поскольку значения создаются компонентом Компонент Database Engine Database Engine при вставке, ни один из этих столбцов не может быть определен в @MyTableVar . Because these values are generated by the Компонент Database Engine Database Engine during the insert operation, neither of these columns can be defined in @MyTableVar .

Х. V. Вставка данных, возвращенных предложением OUTPUT Inserting data returned from an OUTPUT clause

В следующем примере производится отслеживание данных, возвращаемых предложением OUTPUT инструкции MERGE, а затем производится вставка этих данных в другую таблицу. The following example captures data returned from the OUTPUT clause of a MERGE statement, and inserts that data into another table. В инструкции MERGE ежедневно обновляется столбец Quantity таблицы ProductInventory на основе заказов, обработанных в таблице SalesOrderDetail базы данных AdventureWorks2012 AdventureWorks2012 . The MERGE statement updates the Quantity column of the ProductInventory table daily, based on orders that are processed in the SalesOrderDetail table in the AdventureWorks2012 AdventureWorks2012 database. Инструкция также удаляет строки с продуктами, запас которых сократился до 0. It also deletes rows for products whose inventories drop to 0. В примере собираются удаленные строки и вставляются в другую таблицу, ZeroInventory , в которой ведется учет закончившихся продуктов. The example captures the rows that are deleted and inserts them into another table, ZeroInventory , which tracks products with no inventory.

Ц. W. Вставка данных с помощью параметра SELECT Inserting data using the SELECT option

В следующем примере показано, как вставить несколько строк данных с помощью инструкции INSERT с параметром SELECT. The following example shows how to insert multiple rows of data using an INSERT statement with a SELECT option. Первая инструкция INSERT напрямую использует инструкцию SELECT для получения данных из исходной таблицы и сохранения результирующего набора в таблице EmployeeTitles . The first INSERT statement uses a SELECT statement directly to retrieve data from the source table, and then to store the result set in the EmployeeTitles table.

X. X. Указание метки с инструкцией INSERT Specifying a label with the INSERT statement

В следующем примере показано использование метки с инструкцией INSERT. The following example shows the use of a label with an INSERT statement.

Ш. Y. Использование метки и указания запроса с инструкцией INSERT Using a label and a query hint with the INSERT statement

Этот запрос показывает базовый синтаксис для использования метки и указания на соединение с запросом с инструкцией INSERT. This query shows the basic syntax for using a label and a query join hint with the INSERT statement. После отправки запроса к узлу управления SQL Server SQL Server , выполняющемуся на вычислительных узлах, будет применена стратегия хэш-соединения при создании плана запроса SQL Server SQL Server . After the query is submitted to the Control node, SQL Server SQL Server , running on the Compute nodes, will apply the hash join strategy when it generates the SQL Server SQL Server query plan. Дополнительные сведения об указаниях по соединению и использованию предложения OPTION см. в разделе OPTION (SQL Server PDW). For more information on join hints and how to use the OPTION clause, see OPTION (SQL Server PDW).

Оператор INSERT

Оператор INSERT вставляет новые записи в таблицу. При этом значения столбцов могут представлять собой литеральные константы, либо являться результатом выполнения подзапроса. В первом случае для вставки каждой строки используется отдельный оператор INSERT ; во втором случае будет вставлено столько строк, сколько возвращается подзапросом.

Синтаксис оператора следующий:

Как видно из представленного синтаксиса, список столбцов не является обязательным (об этом говорят квадратные скобки в описании синтаксиса). В том случае, если он отсутствует, список вставляемых значений должен быть полный, то есть обеспечивать значения для всех столбцов таблицы. При этом порядок значений должен соответствовать порядку, заданному оператором CREATE TABLE для таблицы, в которую вставляются строки. Кроме того, эти значения должны относиться к тому же типу данных, что и столбцы, в которые они вносятся. В качестве примера рассмотрим вставку строки в таблицу Product, созданную следующим оператором CREATE TABLE :

Пусть требуется добавить в эту таблицу модель ПК 1157 производителя B. Это можно сделать следующим оператором:

Если задать список столбцов, то можно изменить «естественный» порядок их следования:

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

Отметим, что здесь значения всех столбцов имеют значения по умолчанию (первые два — NULL, а последний столбец — type — PC). Теперь мы могли бы написать:

В этом случае отсутствующее значение при вставке строки будет заменено значением по умолчанию — PC. Заметим, что если для столбца в операторе CREATE TABLE не указано значение по умолчанию и не указано ограничение NOT NULL , запрещающее использование NULL в данном столбце таблицы, то подразумевается значение по умолчанию NULL .

Возникает вопрос: а можно ли не указывать список столбцов и, тем не менее, воспользоваться значениями по умолчанию? Ответ положительный. Для этого нужно вместо явного указания значения использовать зарезервированное слово DEFAULT :

Поскольку все столбцы имеют значения по умолчанию, для вставки строки со значениями по умолчанию можно было бы написать:

Однако для этого случая предназначена специальная конструкция DEFAULT VALUES (см. синтаксис оператора), с помощью которой вышеприведенный оператор можно переписать в виде

Заметим, что при вставке строки в таблицу проверяются все ограничения, наложенные на данную таблицу. Это могут быть ограничения первичного ключа или уникального индекса, проверочные ограничения типа CHECK , ограничения ссылочной целостности. В случае нарушения какого-либо ограничения вставка строки будет отклонена. Рассмотрим теперь случай использования подзапроса. Пусть нам требуется вставить в таблицу Product_D все строки из таблицы Product, относящиеся к моделям персональных компьютеров (type = ‘PC’). Поскольку необходимые нам значения уже имеются в некоторой таблице, то формирование вставляемых строк вручную, во-первых, является неэффективным, а, во-вторых, может допускать ошибки ввода. Использование подзапроса решает эти проблемы:

Использование в подзапросе символа «*» является в данном случае оправданным, так как порядок следования столбцов является одинаковым для обеих таблиц. Если бы это было не так, следовало бы применить список столбцов либо в операторе INSERT , либо в подзапросе, либо в обоих местах, который приводил бы в соответствие порядок следования столбцов:

Здесь, также как и ранее, можно указывать не все столбцы, если требуется использовать имеющиеся значения по умолчанию, например:

В данном случае в столбец type таблицы Product_D будет подставлено значение по умолчанию PC для всех вставляемых строк.

Отметим, что при использовании подзапроса, содержащего предикат, будут вставлены только те строки, для которых значение предиката равно TRUE (не UNKNOWN !). Другими словами, если бы столбец type в таблице Product допускал бы NULL -значение, и это значение присутствовало бы в ряде строк, то эти строки не были бы вставлены в таблицу Product_D.

Преодолеть ограничение на вставку одной строки в операторе INSERT при использовании конструктора строки в предложении VALUES позволяет искусственный прием использования подзапроса, формирующего строку с предложением UNION ALL . Так если нам требуется вставить несколько строк при помощи одного оператора INSERT , можно написать:

Использование UNION ALL предпочтительней UNION даже, если гарантировано отсутствие строк-дубликатов, так как в этом случае не будет выполняться проверка для исключения дубликатов.

Заметим, что MySQL допускает еще одну нестандартную синтаксическую конструкцию, выполняющую вставку строки в таблицу в стиле оператора UPDATE:

Рассмотренный в начале параграфа пример с помощью этого оператора можно переписать так:

INSERT и SELECT – добавление и выборка данных

В теории реляционных баз данных часто фигурирует акроним CRUD, образованный от слов Create, Read, Update, Delete. Обозначает он тот факт, что данные в БД можно

считывать их оттуда,

То есть CRUD обозначает четыре базовых действия с данными, хранимыми в таблицах БД.

При этом операторы языка SQL не обязательно совпадают со словами create, read, update, delete. Так в SQL нет оператора READ, вместо него используется SELECT. Записи-строки в таблицу вставляются не с помощью CREATE, а оператором INSERT.

Оператор INSERT

С помощью оператора INSERT языка SQL выполняется вставка данных в таблицу. Синтаксис команды:

После INSERT INTO указывается имя таблицы, после в скобках перечисляются столбцы. После слова VALUES перечисляются данные, вставляемые в поля столбцов. Например:

При этом столбцы не обязательно должны перечисляться в том же порядке, в котором задавались при создании таблицы:

Однако, поскольку можно вообще не указывать имена столбцов, в этом случае при указании значений их порядок должен совпадать со схемой таблицы:

Если в таблице есть столбцы с ограничителями AUTOINCREMENT и DEFAULT, то есть автозаполняемые, значения для них можно не указывать. Однако в этом случае должен быть указан перечень столбцов для остальных значений:

Здесь в первом случае мы вручную задаем значение для поля _id и передаем данные во все остальные поля. Поэтому можем опустить перечисление столбцов. Во втором случае СУБД будет самостоятельно заполнять поле _id. Во избежание неоднозначности мы должны перечислить остальные столбцы.

Обратите внимание, в SQLite мы должны включать поддержку внешнего ключа, чтобы работал ограничитель FOREIGN KEY и не давал нам добавлять записи с номерами тем, которых нет в таблице sections.

Причина, по которой СУБД присвоила второй записи идентификатор 3, а не 2, заключается в том, что раньше в таблицу уже помещались данные, но были удалены.

Оператор SELECT

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

Такая команда отображает значения всех столбцов и строк заданной таблицы. На выборку всех столбцов указывает звездочка после слова SELECT. А все строки будут выбраны потому, что после имени таблицы нет оператора WHERE языка SQL. WHERE позволяет задавать условие, согласно которому отображаются только удовлетворяющие ему строки.

Утилита sqlite3 позволяет отображать данные таблицы в различных форматах, которые задаются с помощью команды .mode, после которой указывается необходимый режим. Команда .mode без аргумента показывает текущий режим.

Обратите внимание, на скринах выше разделителями между столбцами является вертикальная черта. Это режим list. Посмотреть все доступные режимы можно с помощью команды .help .mode .

Чтобы отобразить заголовки используется команда .header on . Они хорошо сочетаются с режимом column. Для отключения заголовков используется .header off :

Когда требуется просмотреть только отдельные столбцы, то вместо звездочки их имена перечисляются через запятую:

WHERE

Условие WHERE используется не только с оператором SELECT, также с UPDATE и DELETE. С помощью WHERE определяются строки, которые будут выбраны, обновлены или удалены. По сути это фильтр.

После ключевого слова WHERE записывается логическое выражение, которое может быть как простым (содержащим операторы = или ==, >, =, Добавить комментарий

Илон Маск рекомендует:  Else - Ключевое слово Delphi
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL