Как сгенерировать конкатенированный первичный ключ при импорте CSV (MariaDB/MySQL)?

Я импортирую прошлые счета из файлов CSV в таблицу MariaDB (MySQL).

Счет id построен на других полях: client-order[variant][-subinvoice]

например. 0123-5c-0

До сих пор значения для id вычислялись пакетно с помощью этого SQL-запроса:

UPDATE invoices SET
id = CONCAT (client,'-',
             order,
             IFNULL(variant,''),
             IF(subinvoice IS NULL, '',CONCAT('-',subinvoice))
             );

Поскольку столбец id теперь является PRIMARY KEY, я нужно преобразовать приведенный выше запрос в триггер генерирует id «на лету» при вставке данных из записей CSV.

Вот одно из возможных решений. (Пользователь P. Salmon, который помог мне отладить мой код; спасибо ему!)

DELIMITER //
DROP TRIGGER IF EXISTS invoice_generate_id//
CREATE TRIGGER invoice_generate_id 
BEFORE INSERT ON invoices
FOR EACH ROW
BEGIN
  SET NEW.id = CONCAT (new.client,'-',
         new.order,
         IFNULL(new.variant,''),
         IF(new.subinvoice IS NULL, '',CONCAT('-',new.subinvoice))
         );
END//
DELIMITER ;

В этом есть ряд неправильных вещей, которые вы не можете иметь, и if..else..end, если как часть оператора concat - вам нужен оператор SET для установки NEW.value, и я подозреваю, что клиент, вариант и дополнительный счет-фактура должны быть предшествует NEW. Также вы можете сделать это как часть оператора load data infile - см. руководство, где это относится к переменным. –

P.Salmon 20.04.2019 13:06

Спасибо. Вы были абсолютно правы. Я обновил код допустимым на основе ваших предложений и синтаксиса, который использовал мой пакетный SQL-запрос. Н.Б. При создании триггера phpMyAdmin упоминает ошибку в точке с запятой, которая заканчивается выражением SET(). Просто нужно игнорировать его, так как триггер действителен.

OuzoPower 20.04.2019 16:02
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
2
41
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот триггер, который синтаксически в порядке. Обратите внимание на использование слияния

DELIMITER //
DROP TRIGGER IF EXISTS invoice_generate_id//
CREATE TRIGGER invoice_generate_id 
BEFORE INSERT ON invoices
FOR EACH ROW
BEGIN
  set NEW.id = CONCAT (new.client,'-',
             new.order,
                 coalesce(concat('-',new.variant,''),''),
                 coalesce(concat('-',new.subinvoice,''),'') 
                 )
    ;
END//
DELIMITER ;

Спасибо за ваш триггер, который синтаксически в порядке. Это было большим подспорьем. Использование «слияния» элегантно. Для variant мы должны избегать окружающего concat, если ссылаемся на мой исходный пример (поскольку вариант не предварялся дефисом). Для subinvoice я оставил функции IF() и CONCAT(), потому что они облегчают понимание кода, если я перечитаю код через несколько месяцев, хотя должен признать, что COALESCE() более элегантен.

OuzoPower 20.04.2019 16:09

Другие вопросы по теме