Я хочу создать таблицу и затем инициализировать ее с некоторыми значениями, как можно более кратко.
Однако этот сценарий выполняется каждый раз, когда запускается мое приложение, поэтому вставка должна выполняться только для элементов.которые еще не были добавлены ранее.
Я не хочу использовать директиву IGNORE в INSERT IGNORE INTO, потому что не хочу игнорировать непредвиденные ошибки.
По какой-то причине INSERT INTOзавершается с ошибкой «Ошибка SQL (1136): счетчик столбцов не совпадает со счетчиком значений в строке 1», хотя следующий выбор дает значения, которые необходимо добавить.
Вот код ошибки:
START TRANSACTION;
CREATE TABLE IF NOT EXISTS `privileges` (
`id` TINYINT NOT NULL AUTO_INCREMENT,
`label` VARCHAR(25) UNIQUE,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `privileges` (`label`)
SELECT `label` FROM (
SELECT NULL AS `label`
UNION VALUES
('item1'),
('item2')
) X
WHERE `label` IS NOT NULL
AND `label` NOT IN (SELECT `label` FROM `privileges`)
COMMIT;
В настоящее время я решаю эту проблему, сначала вставляя значения во временную таблицу, а затем выполняю выборку для этого.Но почему вышеприведенное не работает и есть более краткий способ сделать то, что я пытаюсь сделать?
Я использую MariaDB 10.3.9, добавлено отсутствующее уникальное ограничение
Редактировать 2: Спасибо LukStorms за выяснение, что ошибка была связана с AUTO_INCREMENT, кажется, что передача NULL для столбца AUTO_INCREMENT решает проблему следующим образом:
INSERT INTO `privileges` (id, label)
WITH ITEMS(label) AS (VALUES
('users:read'),('users:create'),
('clients:read'),('clients:write'),
('catalog:read'),('catalog:write'),
('cart:read'),('cart:write'),
('orders:read'),('orders:write'), ('test1')
) SELECT NULL, label FROM ITEMS i
WHERE label NOT IN (SELECT label FROM `privileges`);