Мой вопрос довольно сложный, но я решил попробовать.
Короче говоря, я хочу вставить строку с slug
(короткая строка с альфами и тире: this-is-a-slug). Проблема в том, что slug
– это уникальный ключ, и могут быть дубликаты.
Когда есть дубликат, он должен быть вставлен с измененным slug
, например, с суффиксом: this-is-a-slug-1, если это не приведет к увеличению суффикса: this-is-a-slug-2.
Вот сложная часть, она должна быть выполнена в MySQL (без использования PHP) и предпочтительно в инструкции INSERT (без переменных, процедур и т. Д.),
Я пробовал простое решение:
INSERT INTO table (slug) VALUES(IF((SELECT COUNT(slug) FROM table WHERE slug = 'this-is-a-slug') > 0, 'this-is-a-slug-1', 'this-is-a-slug');
Это должно вставить this-is-a-slug-1
если this-is-a-slug
существует, или this-is-a-slug
противном случае.
Ожидается, однако, что это порождает ошибку, сообщающую мне, что я не могу вам оператора FROM
инструкции UPDATE
или что-то в этом роде.
В этом проблема, надеюсь, что кто-то может что-то сказать об этом.
PS: Это используется в действительно обновляемой процедуре обновления новостей RSS, в которой я могу легко проверить пул в db с помощью php, а затем изменить его, но это удваивает время моего скрипта: |, поэтому я думал, что смогу сделать это трудно для mysql, а не php.
Вы можете создать триггер, который изменит значение NEW.slug перед его вставкой.
drop trigger if exists changeSlug; delimiter | CREATE TRIGGER changeSlug BEFORE INSERT ON slugs FOR EACH ROW BEGIN declare original_slug varchar(255); declare slug_counter int; set original_slug = new.slug; set slug_counter = 1; while exists (select true from slugs where slug = new.slug) do set new.slug = concat(original_slug, '-', slug_counter); set slug_counter = slug_counter + 1; end while; END; | delimiter ;
И это будет результат
mysql> insert into slugs values ("dude"); Query OK, 1 row affected (0.00 sec) mysql> insert into slugs values ("dude"); Query OK, 1 row affected (0.00 sec) mysql> insert into slugs values ("dude"); Query OK, 1 row affected (0.00 sec) mysql> select * from slugs; +--------+ | slug | +--------+ | dude | | dude-1 | | dude-2 | +--------+ 3 rows in set (0.00 sec)