Limak
Limak

Reputation: 47

Another "#1054: Unknown column in 'field list'" mystery

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;

Upvotes: 1

Views: 878

Answers (1)

fifonik
fifonik

Reputation: 1606

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.

Upvotes: 0

Related Questions