Ошибка MySQL: операнд должен содержать 1 столбец (столбцы) при простом запросе на обновление - PullRequest
0 голосов
/ 31 августа 2018

У меня есть хранимая процедура в MySQL, которая должна обновлять таблицу с именем 'task' значением, зависящим от условий. Проблема в следующем ряду

UPDATE task SET validity = 1 WHERE id = _task_id;

Этот запрос ничего не делает, хотя в этом случае он работает:

UPDATE task SET validity = NULL WHERE id = _task_id;

Хранимая процедура выполняется при вызове со страницы PHP, и я уверен, что все параметры IN верны, поскольку остальные строки процедуры выполняются правильно.

Вот определение таблицы 'task':

  CREATE TABLE task(
  id INT AUTO_INCREMENT NOT NULL,
  camp_id INT NOT NULL,
  heading VARCHAR(200) NOT NULL UNIQUE,
  description VARCHAR(300) NOT NULL,
  validity INT(1),
  PRIMARY KEY(id),
  CONSTRAINT task_fk
  FOREIGN KEY(camp_id) REFERENCES work_campaign(id)
  ON DELETE CASCADE
) ENGINE = InnoDB;

Хранимая процедура:

    DELIMITER //

    DROP PROCEDURE IF EXISTS define_task_result;
    CREATE PROCEDURE define_task_result(IN _task_id INT, IN count_answers INT)
    BEGIN
      DECLARE _camp_id INT;
      DECLARE _validity_threshold INT;
      DECLARE count_answer_options INT;
      DECLARE counter INT unsigned;
      DECLARE _option VARCHAR(100);
      DECLARE _percentage INT;
      DECLARE max_percentage INT;
      DECLARE selected_option_number INT;
      DECLARE check_max_number INT;


      SET _camp_id = (SELECT camp_id FROM task WHERE id = _task_id);
      SET _validity_threshold = (SELECT validity_threshold FROM work_campaign WHERE id = _camp_id);
      SET counter = 0;

      DROP TABLE IF EXISTS options_percentage;
      CREATE TABLE options_percentage (
       opt VARCHAR(100),
       percentage INT DEFAULT 0
      );

      INSERT INTO options_percentage(opt)
      SELECT answer_option FROM task_answers_options WHERE task_id = _task_id;

      SET count_answer_options = (SELECT COUNT(*) FROM options_percentage);

      WHILE counter < count_answer_options DO
        SET _option = (SELECT opt FROM options_percentage LIMIT counter,1);
        SET selected_option_number = (SELECT COUNT(*) FROM task_worker_answers WHERE answer = _option);
        SET _percentage = (selected_option_number / count_answers) * 100;
        UPDATE options_percentage SET percentage = _percentage WHERE opt = _option;
        SET counter = counter + 1;
      END WHILE;

  SET check_max_number = (SELECT COUNT(*) FROM options_percentage WHERE percentage = (SELECT MAX(percentage) FROM options_percentage));

  IF check_max_number > 1 THEN
    UPDATE task SET validity = NULL WHERE id = _task_id;
  ELSE
    SET max_percentage = (SELECT percentage FROM options_percentage WHERE percentage = (SELECT MAX(percentage) FROM options_percentage LIMIT 1));

    IF max_percentage >= _validity_threshold THEN
      UPDATE task SET validity = 1 WHERE id = _task_id;
    ELSE
      UPDATE task SET validity = NULL WHERE id = _task_id;
    END IF;
  END IF;


    END //

    DELIMITER ;

Когда я пытался вызвать тот же запрос из командной строки, он выдавал следующую ошибку - Операнд должен содержать 1 столбец (столбцы) . Я действительно не вижу, как это исправить ..

1 Ответ

0 голосов
/ 31 августа 2018

У вас есть запрос запроса, возвращающий более одного значения.

Это здесь. Он находится в верхней части оператора ELSE, который содержит вашу «строку проблемы» из исходного вопроса.

SET max_percentage = (SELECT percentage FROM options_percentage WHERE percentage = (SELECT MAX(percentage) FROM options_percentage));

Объяснение ниже

SELECT MAX(percentage) FROM options_percentage

Это хорошо, он вернет только одно значение.

SELECT percentage FROM options_percentage WHERE percentage = {scalar}

Это не всегда верно. Что происходит, когда происходит несколько percentage совпадений?

Вы можете использовать TOP в SQL Server, чтобы ограничить свои результаты. Другие RMDB имеют аналогичные функции, которые вы можете искать. Я полагаю, что MySQL эквивалент LIMIT и он идет в конце SELECT Statement. Надеюсь, это поможет.

В ответ на ваш вопрос обновление 8/31

Это то, что у вас есть (SELECT MAX(percentage) FROM options_percentage LIMIT 1))

Это должно стать этим (SELECT MAX(percentage) FROM options_percentage )LIMIT 1)

В настоящее время вы LIMIT задаете «хороший» запрос, а не тот, который имеет проблему.

Таким образом, полная строка с указанным выше изменением будет такой:

SET max_percentage = (SELECT percentage FROM options_percentage WHERE percentage = (SELECT MAX(percentage) FROM options_percentage) LIMIT 1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...