mysql вызов функции внутри хранимой процедуры с использованием phpmyadmin - PullRequest
0 голосов
/ 24 января 2020

У меня есть следующий код, который работает:

BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE user_id int(11);
  DECLARE cur1 CURSOR FOR SELECT id FROM users;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  # drop and re-create user_rank TABLE

  DROP TABLE IF EXISTS user_rank;

  CREATE TABLE `user_rank` (
    `id` int(11) UNSIGNED NOT NULL,
    `has_hobbies` int(3) DEFAULT 0,
    `passed_test` int(3) DEFAULT 0,
    `has_picture` int(3) DEFAULT 0,
    `won_a_job` int(3) DEFAULT 0,
    `is_prolancer` int(3) DEFAULT 0,
    `is_verified` int(3) DEFAULT 0,
    `has_portfolio` int(3) DEFAULT 0,
    `has_likes` int(3) DEFAULT 0,
    `has_disputes` int(3) DEFAULT 0,
    `has-earnings` int(3) DEFAULT 0,
    `has_feebacks` int(3) DEFAULT 0,
    `has_invitations` int(3) DEFAULT 0,
    `has_views` int(3) DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `user_rank`
    ADD PRIMARY KEY (`id`);

ALTER TABLE `user_rank`
    MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;

OPEN cur1;

read_loop: LOOP
FETCH cur1 INTO user_id;
IF done THEN
  LEAVE read_loop;
END IF;
INSERT INTO user_rank (id) values (user_id);
END LOOP;

CLOSE cur1;
END

он зацикливает пользователей таблицы с помощью курсора и копирует все идентификаторы пользователей в таблицу user_rank. У меня есть функция с именем hasUserPassedTest, определенная в моей базе данных, которая дает идентификатор пользователя, возвращающий 10 или 0. Я хотел бы вызвать функцию в l oop выше и вставить ее в таблицу user_rank, но следующий код не работает :

BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE user_id int(11);
DECLARE cur1 CURSOR FOR SELECT id FROM users;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

# drop and re-create user_rank TABLE

DROP TABLE IF EXISTS user_rank;

CREATE TABLE `user_rank` (
    `id` int(11) UNSIGNED NOT NULL,
    `has_hobbies` int(3) DEFAULT 0,
    `passed_test` int(3) DEFAULT 0,
    `has_picture` int(3) DEFAULT 0,
    `won_a_job` int(3) DEFAULT 0,
    `is_prolancer` int(3) DEFAULT 0,
    `is_verified` int(3) DEFAULT 0,
    `has_portfolio` int(3) DEFAULT 0,
    `has_likes` int(3) DEFAULT 0,
    `has_disputes` int(3) DEFAULT 0,
    `has-earnings` int(3) DEFAULT 0,
    `has_feebacks` int(3) DEFAULT 0,
    `has_invitations` int(3) DEFAULT 0,
    `has_views` int(3) DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `user_rank`
    ADD PRIMARY KEY (`id`);

ALTER TABLE `user_rank`
    MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;

OPEN cur1;

read_loop: LOOP
    FETCH cur1 INTO user_id;
    IF done THEN
    LEAVE read_loop;
    END IF;
    INSERT INTO user_rank (id, has_hobbies) values (user_id, CALL 
    hasUserPassedTest(user_id));
 END LOOP;

  CLOSE cur1;
END

Я использую CALL для вызова моей функции внутри хранимой процедуры, но она не работает. Как мне вызвать мою функцию в хранимой процедуре?

1 Ответ

1 голос
/ 24 января 2020

Я использую CALL для вызова моей функции внутри хранимой процедуры, но не работает

CALL не используется для выполнения функции.

Оператор CALL

Оператор CALL вызывает хранимую процедуру, которая была ранее определена с помощью CREATE PROCEDURE.


это зацикливает пользователей таблицы с помощью курсора и копирует все идентификаторы пользователей в таблицу user_rank.

Почему так сложно? процедура, курсор, обработчик, l oop ... достаточно простого запроса:

INSERT INTO user_rank (id, has_hobbies) 
SELECT user_id, hasUserPassedTest(user_id)
FROM users;

UPDATE

Вставка может сочетаться с созданием таблицы:

CREATE TABLE `user_rank` (
    `id` int(11) UNSIGNED NOT NULL,
    `has_hobbies` int(3) DEFAULT 0,
    `passed_test` int(3) DEFAULT 0,
    `has_picture` int(3) DEFAULT 0,
    `won_a_job` int(3) DEFAULT 0,
    `is_prolancer` int(3) DEFAULT 0,
    `is_verified` int(3) DEFAULT 0,
    `has_portfolio` int(3) DEFAULT 0,
    `has_likes` int(3) DEFAULT 0,
    `has_disputes` int(3) DEFAULT 0,
    `has-earnings` int(3) DEFAULT 0,
    `has_feebacks` int(3) DEFAULT 0,
    `has_invitations` int(3) DEFAULT 0,
    `has_views` int(3) DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8
SELECT user_id AS id, hasUserPassedTest(user_id) AS has_hobbies
FROM users;

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

CREATE TABLE `user_rank` (
    `id` int(11) UNSIGNED NOT NULL,
    `has_hobbies` int(3) DEFAULT 0,
    `passed_test` int(3) DEFAULT 0,
    `has_picture` int(3) DEFAULT 0,
    `won_a_job` int(3) DEFAULT 0,
    `is_prolancer` int(3) DEFAULT 0,
    `is_verified` int(3) DEFAULT 0,
    `has_portfolio` int(3) DEFAULT 0,
    `has_likes` int(3) DEFAULT 0,
    `has_disputes` int(3) DEFAULT 0,
    `has-earnings` int(3) DEFAULT 0,
    `has_feebacks` int(3) DEFAULT 0,
    `has_invitations` int(3) DEFAULT 0,
    `has_views` int(3) DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8
SELECT user_id AS id, 
       hasUserPassedTest(user_id) AS has_hobbies
       0 AS `passed_test`,
       0 AS `has_picture`,
       0 AS `won_a_job`,
       0 AS `is_prolancer`,
       0 AS `is_verified`,
       0 AS `has_portfolio`,
       0 AS `has_likes`,
       0 AS `has_disputes`,
       0 AS `has-earnings`,
       0 AS `has_feebacks`,
       0 AS `has_invitations`,
       0 AS `has_views`
FROM users;

DROP TABLE остается отдельным запросом: (

...