Я пытаюсь создать динамически названные таблицы MySQL в подпрограммах, используя префикс на основе номера модели, который я установил в php как переменная @ModelRef
.
Обычно я могу создавать таблицы без проблем, но иногда сбой при попытке записи данных во вновь созданную таблицу. Следующий код работает:
SET @TableName = CONCAT(''',@ModelRef, '_', 'input_actual_php',''');
SET @Table_Text:=CONCAT('CREATE TABLE IF NOT EXISTS ',@TableName, ' (
case_id INT PRIMARY KEY DEFAULT 1,
Savings1 DECIMAL(10,2) DEFAULT NULL,
Savings2 DECIMAL(10,2) DEFAULT NULL,
TermDeposit DECIMAL(10,2) DEFAULT NULL,
FC_Dist INT DEFAULT NULL)'
);
PREPARE stmt from @Table_Text;
EXECUTE stmt;
-- Write values to table
SET @TableEdit:=CONCAT('INSERT INTO ',@TableName,' VALUES
(case_id, @Savings1, @Savings2, @TermDeposit, @FC_Dist)');
PREPARE stmt from @TableEdit;
EXECUTE stmt;
и, тем не менее, следующий код в другой процедуре не работает:
SET @TableName_1 = CONCAT(''', @ModelRef, '_lookup_wage_growth',''');
SET @Table_Text_1:=CONCAT('CREATE TABLE IF NOT EXISTS ',@TableName_1, ' (
Age INT PRIMARY KEY DEFAULT 0,
ModYear INT DEFAULT 0,
Growth_1 DECIMAL(5 , 3 ) DEFAULT 0,
GrowthInd_1 DECIMAL(5 , 3 ) DEFAULT 0,
NomWage_1 INT DEFAULT 0,
NomWage_1_UD INT DEFAULT 0)'
);
PREPARE stmt from @Table_Text_1;
EXECUTE stmt;
-- Code here doing calculations and generating values
-- Write to table
SET @TableEdit_1:=CONCAT('INSERT INTO ',@TableName_1,' VALUES
(age_var, ModYear_var, Growth_1_var, GrowthInd_1_var, NomWage_1_var, @NomWage_1_UD)');
PREPARE stmt from @TableEdit_1;
EXECUTE stmt;
Я пробовал и играл с различными вариантами выше и упрощал все, и все же я не могу понять, почему вторая подпрограмма не может писать в таблицу и сбой. Что-то мне не хватает?
Я бы рекомендовал против этого шаблона вообще. Что не так с наличием одной таблицы с полем "modelRef"?
Но если вам нужно/нужно поступить с ним таким образом по какой-то причине; похоже, что вы вставляете age_var
в Age
, а age_var
нигде не определен, и я не уверен, будет ли он доступен даже из инструкции PREPAREd, если только это не является переменной user/session/@.
Предполагая, что он был DECLAREd в "выполнении вычислений и генерации значений"; вам понадобится
SET @TableEdit_1:=CONCAT('INSERT INTO ',@TableName_1,'
VALUES (', age_var, ', ', ModYear_var, ', ' ....
Кроме того, я склонен ошибаться на стороне осторожности и постфиксации большинства @-variable идентификаторов в хранимых процедурах с помощью guid, который я генерирую для этой процедуры. В конечном итоге вы можете легко отслеживать ошибки, используя эффективные глобальные переменные (для подключения).
Благодарим за предоставленные комментарии и рекомендации. Я взял их на борт и изменил свой подход.
Вместо создания и записи динамически помеченных таблиц я изменил их создание из CREATE TABLE
чтобы создать CREATE TEMPORARY TABLE
и это устранило конфликт, созданный между пользователями, управляющими таблицами с общими именами. Временные таблицы сохраняются до тех пор, пока соединение с базой данных существует и создается для каждого пользователя и сразу же отбрасывается, достаточно долго для обычного расчета и извлечения данных на клиентскую сторону.