Как преобразовать запрос SQL с помощью LOCK TABLE в хранимую процедуру с помощью SELECT ... FOR UPDATE - PullRequest
0 голосов
/ 28 января 2020

Я пытаюсь спроецировать категории постов на своем веб-сайте (обучение PHP) и решил использовать вложенный стиль Майка Хиллиера, который я нашел на ЕГО СТРАНИЦЕ

Проблема, с которой я столкнулся является то, что я хочу установить его методы как «хранимые процедуры» на моем сервере phpMyAdmin SQL, НО добавление узлов и удаление их использует LOCK TABLE, который запрещено использовать в хранимых процедурах. Может кто-нибудь сказать мне, как преобразовать один из его SQL запросов в один работающий в хранимой процедуре, и объяснить, почему?

Первый запрос на добавление узлов:

LOCK TABLE nested_category WRITE;

SELECT @myRight := rgt FROM nested_category
WHERE name = 'TELEVISIONS';

UPDATE nested_category SET rgt = rgt + 2 WHERE rgt > @myRight;
UPDATE nested_category SET lft = lft + 2 WHERE lft > @myRight;

INSERT INTO nested_category(name, lft, rgt) VALUES('GAME CONSOLES', @myRight + 1, @myRight + 2);

UNLOCK TABLES;

Я обнаружил, что есть что-то вроде метода SELECT ... FOR UPDATE, но я абсолютный новичок в SQL и не могу разберись сам; /

1 Ответ

2 голосов
/ 28 января 2020

Я думаю, вам следует начать с этой статьи: https://www.mysqltutorial.org/getting-started-with-mysql-stored-procedures.aspx

Я не вижу BEGIN, END и CREATE PROCEDURE в вашем запросе, так что я думаю, что вы есть здесь можно просто запустить как необработанный запрос, а не процедура.

Прежде чем создавать новую процедуру, вы должны определить, что эта процедура должна делать? Я прочитал статью, которую вы отправили, и похоже, что она была ответственна за добавление узлов.

Позволяет назвать это addNode. Первый параметр должен быть parent (это будет имя родительского узла - 'TELEVISION' в вашем примере. Имя файла должно быть вторым, как child ('GAME CONSOLES'). Оба типа должны иметь тот же тип, что и столбец name в nested_category table.

DELIMITER //

CREATE PROCEDURE addNode(
    parent varchar(20),
    child varchar(20)
)
BEGIN
    -- << you will figure this out :) >>
    -- SELECT [...] WHERE name = parent
    -- UPDATE [...]
    -- INSERT [...] VALUES(child, [...]
END //

DELIMITER ;

Теперь в вашем PHP вы можете запустить:

CALL addNode('TELEVISION', 'GAME CONSOLES');

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

PS: я не проверял этот запрос. Надеюсь, он в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...