2014-01-07 4 views
1

Фон - у меня есть БД, созданный из одного большого плоского файла. Вместо создания одной большой таблицы с 106 столбцами. Я создал таблицу «столбцов», в которой хранятся имена столбцов и идентификатор таблицы, содержащей эти данные, а также 106 других таблиц для хранения данных для каждого столбца. Поскольку не все записи имеют данные во всех столбцах, я думал, что это может быть более эффективным способом загрузки данных (может быть, плохая идея).Временные таблицы MySQL не очищаются

Сложность этого заключалась в том, чтобы восстановить одну запись из этой структуры. Для облегчения этого я создал следующую процедуру:

DROP PROCEDURE IF EXISTS `col_val`; 
delimiter $$ 

CREATE PROCEDURE `col_val`(IN id INT) 
BEGIN 
    DROP TEMPORARY TABLE IF EXISTS tmp_record; 
    CREATE TEMPORARY TABLE tmp_record (id INT(11), val varchar(100)) ENGINE=MEMORY; 
    SET @ctr = 1; 
    SET @valsql = ''; 
    WHILE (@ctr < 107) DO 
     SET @valsql = CONCAT('INSERT INTO tmp_record SELECT ',@ctr,', value FROM col',@ctr,' WHERE recordID = ',@id,';'); 
     PREPARE s1 FROM @valsql; 
     EXECUTE s1; 
     DEALLOCATE PREPARE s1; 
     SET @ctr = @ctr+1; 
     END WHILE; 
END$$ 
DELIMITER ; 

Затем я использую следующий SQL, где хранятся параметр процедуры является идентификатором записи я хочу.

CALL col_val(10); 
SELECT c.`name`, t.`val` 
FROM `columns` c INNER JOIN tmp_record t ON c.ID = t.id 

Проблема. В первый раз, когда я запускаю это, он отлично работает. Однако каждый последующий прогон возвращает ту же самую запись, даже если параметр изменен. Как это сохраняется, даже когда хранимая процедура должна отбрасываться и воссоздавать временную таблицу?

Возможно, я передумал весь дизайн и вернусь к одной таблице, но проблема иллюстрирует то, что я хотел бы понять.

Неуверенный, если это имеет значение, но я запускаю MySQL 5.6 (64 бит) в Windows 7 и выполняю SQL через MySQL Workbench v5.2.47 CE.

Благодаря,

ответ

0

В MySQL хранимых процедур, не ставят в @ символ перед локальных переменных (входных параметров или локально объявленных переменных). Используемый вами @id относится к user variable, который похож на глобальную переменную для сеанса, с которого вы вызываете процедуру.

Иными словами, @id - это отличная переменная от id.

Это объяснение непосредственной проблемы, с которой вы сталкиваетесь. Однако я бы не проектировал таблицы так, как вы это делали.

Поскольку не все записи имеют данные во всех колонках, я думал, что это могло бы быть более эффективным способом, чтобы загрузить данные

Я рекомендую использовать обычную одну таблицу, а также использовать NULL для обозначения отсутствуют данные.

+0

Спасибо, Билл. Определенно необходимо переработать оригинальный дизайн. Мне странно, что запрос работает в первый раз. вероятно, какая-то странность с переменной, как вы описали, оставаясь в памяти. – NoNV

+0

Да, переменная пользователя сохраняет свое значение в течение всего сеанса. –

Смежные вопросы