Another “#1054: Unknown column in 'field list'” mystery

百般思念 提交于 2020-01-15 10:15:23

问题


Have looked for any solution but unsuccessfully... The mystery is about body of my few functions. I presented two of them below. They are pretty the same but Fun1 works fine and Fun2 doesn't. The error is as in topic - "Unknown column in 'field list'". I've noticed that it rather depends on declared variable type - if it's string (like tadnotation) there is no problem met, if it's time, decimal, enum, it causes errors. Can someone explain it to me? And of course I'm also searching for the solution, so every tip is welcome.

Inputs are the same for every function:

(`vtable` ENUM('user','client', 'daily_operation','monthly_operation'), 
`vclient_id` SMALLINT,
`vuser_id` SMALLINT, 
`vid` INT,
`vedition_id` TINYINT)

Fun1:

DELIMITER $$

CREATE DEFINER=`root`@`localhost` FUNCTION `getAdnotation` (`vtable` ENUM('user', 'client', 'daily_operation', 'monthly_operation'), `vclient_id` SMALLINT, `vuser_id` SMALLINT, `vid` INT, `vedition_id` TINYINT) RETURNS TINYTEXT CHARSET utf8
BEGIN

DECLARE tadnotation TINYTEXT;

SET @tadnotation = CASE
    WHEN vtable = 'daily_operation' THEN 
        (SELECT adnotation FROM daily_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1)
    WHEN vtable = 'monthly_operation' THEN 
        (SELECT adnotation FROM monthly_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1)
END;
RETURN @tadnotation;

END$$

Fun2:

DELIMITER $$

CREATE DEFINER=`root`@`localhost` FUNCTION `getStartTime` (`vtable` ENUM('user', 'client', 'daily_operation', 'monthly_operation'), `vclient_id` SMALLINT, `vuser_id` SMALLINT, `vid` INT, `vedition_id` TINYINT) RETURNS TIME
BEGIN

DECLARE tstart_time TIME;

SET @tstart_time = CASE
    WHEN vtable = 'daily_operation' THEN 
        (SELECT start_time FROM daily_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1)
    WHEN vtable = 'monthly_operation' THEN 
        (SELECT start_time FROM monthly_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1)
END;
RETURN @tstart_time;

END$$

Table (only 'daily_operation' because 'monthly_operation' is similar):

CREATE TABLE `daily_operation` (
  `client_id` smallint(6) NOT NULL,
  `user_id` smallint(6) NOT NULL,
  `id` int(11) NOT NULL,
  `edition_id` tinyint(4) NOT NULL,
  `start_time` time NOT NULL,
  `end_time` time NOT NULL,
  `duration_minutes` smallint(6) NOT NULL,
  `duration_hours` decimal(4,2) NOT NULL,
  `adnotation` tinytext
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

What works is if I change SET-CASE clause with:

IF(vtable = 'daily_operation') THEN
    SET @tstart_time = (SELECT start_time FROM daily_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1);
ELSEIF(vtable = 'monthly_operation') THEN
    SET @tstart_time = (SELECT start_time FROM monthly_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1);
END IF;

回答1:


For me assignment with CASE expression is a bit confusing (hard to read) so I'd use CASE clause with INTO @var instead:

BEGIN
CASE
    WHEN vtable = 'daily_operation' THEN 
        SELECT start_time INTO @result FROM daily_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1;
    WHEN vtable = 'monthly_operation' THEN 
        SELECT start_time INTO @result FROM monthly_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1;
END CASE;

RETURN @result;
END

Note, you do not need to DECLARE @session_variables used in SP.



来源:https://stackoverflow.com/questions/59147909/another-1054-unknown-column-in-field-list-mystery

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!