Временная таблица в хранимых функциях?
Я пишу функцию, которую мне нужно использовать либо TABLE
переменная для ( я слышал, они не существуют в MySQL) или временная таблица.
Однако кажется, что временные таблицы работают только в хранимых процедурах, а не в функциях. Я продолжаю получать эту ошибку:
Явное или неявное принятие не допускается в хранимой функции или триггере.
То, что я пытаюсь построить, - это решение моего более раннего вопроса. Это функция, которая получает дату начала, дату окончания и строку, разделенную запятыми. Сначала он находит все месяцы между начальной и конечной датой и сохраняет их как отдельные записи в первой временной таблице. Затем он анализирует строку, разделенную запятыми, и сохраняет ее во второй временной таблице. Затем он выполняет выборочное объединение двух, и, если записи присутствуют, он возвращает true, иначе false.
Мое намерение состоит в том, чтобы использовать это как часть других запросов WHERE
предложение, поэтому оно должно быть функцией, а не хранимой процедурой.
Как я могу использовать временные таблицы в хранимых функциях? И если я не могу, что я могу сделать вместо этого?
Вот моя (в настоящее время неработающая) функция (или в сущности):
-- need to parse out a string like '4,2,1' and insert values into temporary table
-- MySQL doesn't have a native string split function, so we make our own
-- taken from: http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/
DROP FUNCTION IF EXISTS SPLIT_STR;
CREATE FUNCTION SPLIT_STR(x VARCHAR(255), delim VARCHAR(12), pos INT) RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos), LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1), delim, '');
-- need to find all months between the start and end date and insert each into a temporary table
DROP FUNCTION IF EXISTS months_within_range;
DELIMITER //
CREATE FUNCTION months_within_range(starts_at DATE, ends_at DATE, filter_range VARCHAR(255)) RETURNS TINYINT
BEGIN
DROP TABLE IF EXISTS months_between_dates;
DROP TABLE IF EXISTS filter_months;
CREATE TEMPORARY TABLE months_between_dates (month_stuff VARCHAR(7));
CREATE TEMPORARY TABLE filter_months (filter_month VARCHAR(7));
SET @month_count = (SELECT PERIOD_DIFF(DATE_FORMAT(ends_at, "%Y%m"), DATE_FORMAT(starts_at, "%Y%m")));
-- PERIOD_DIFF only gives us the one month, but we want to compare to, so add one
-- as in, the range between 2011-01-31 and 2011-12-01 should be 12, not 11
INSERT INTO months_between_dates (month_stuff) VALUES (DATE_FORMAT(starts_at, "%Y-%m"));
SET @month_count = @month_count + 1;
-- start he counter at 1, since we've already included the first month above
SET @counter = 1;
WHILE @counter < @month_count DO
INSERT INTO months_between_dates (month_stuff) VALUES (DATE_FORMAT(starts_at + INTERVAL @counter MONTH, "%Y-%m"));
SET @counter = @counter + 1;
END WHILE;
-- break up the filtered string
SET @counter = 1;
-- an infinite loop, since we don't know how many parameters are in the filtered string
filters: LOOP
SET @filter_month = SPLIT_STR(filter_range, ',', @counter);
IF @filter_month = '' THEN LEAVE filters;
ELSE
INSERT INTO filter_months (filter_month) VALUES (@filter_month);
SET @counter = @counter + 1;
END IF;
END LOOP;
SELECT COUNT(*) INTO @matches FROM months_between_dates INNER JOIN filter_months ON months_between_dates.month_stuff = filter_months.filter_month;
IF @matches >= 1 THEN RETURN 1;
ELSE RETURN 0;
END//
DELIMITER ;
1 ответ
Операторы отбрасывания таблицы вызывают неявную фиксацию, которая недопустима в функции mysql. хотя временная таблица drop не вызывает фиксации. если вы не беспокоитесь о существовании обычных (не временных) таблиц с именем months_between_dates или filter_months, вы можете изменить
DROP TABLE IF EXISTS months_between_dates;
DROP TABLE IF EXISTS filter_months;
в
DROP TEMPORARY TABLE IF EXISTS months_between_dates;
DROP TEMPORARY TABLE IF EXISTS filter_months;