MySQL всегда выдает ошибку, когда делает что-то вроде:Как я могу «SELECT INTO» с неизвестными столбцами?
INSERT INTO `newtable`
(`a`, `b`, `c`, `d`)
SELECT
`a`, `b`, `c` , `d` FROM `oldtable`
, когда поле а и с не существует в «Новая_таблица». Конечно, я понимаю, что это законная ошибка. Я хочу знать, есть ли способ построить что-то вроде case-case для обработки этого. Запрос динамически строится на основе динамической таблицы, поэтому мне неизвестно, какие поля существуют.
Какие у вас сообразительные идеи?
Обратите внимание, что Новая_таблица определяется динамически, как указано выше:
public function updateTableSchema($table, $fields)
{
// Drop the temporary table if exists
$sql = "
DROP TABLE IF EXISTS `temp_{$table}`
";
if (!$this->db()->query($sql)) return FALSE;
// Make a backup of the original table and select the old values into it
$sql = "
CREATE TABLE `temp_{$table}`
SELECT * FROM `$table`
";
if (!$this->db()->query($sql)) return FALSE;
// Drop the old table
if (!$this->db()->query("DROP TABLE `$table`")) return FALSE;
// Recreate the table with the new fields
$sql = "
CREATE TABLE IF NOT EXISTS `$table`
(\n";
$sql .= "`id` int(11) NOT NULL AUTO_INCREMENT,\n";
foreach ($fields as $field)
{
$sql .= html_entity_decode("`$field` varchar(255) NOT NULL,\n");
}
$sql .= "PRIMARY KEY (`id`)\n";
$sql .= "
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
";
if (!$this->db()->query($sql)) return FALSE;
CREATE TABLE new_tbl SELECT * FROM orig_tbl;
// Insert the temporary records into the new table
$sql = "INSERT INTO `$table` (";
foreach ($fields as $field)
{
$sql .= html_entity_decode("`$field`, ");
}
$sql = rtrim($sql, ', ') . ') SELECT ';
foreach ($fields as $field)
{
$sql .= html_entity_decode("`$field`, ");
}
$sql = rtrim($sql, ', ') . " FROM `temp_{$table}`";
print $sql;
if (!$this->db()->query($sql)) return FALSE;
// Drop the temporary table
$sql = "DROP TABLE `temp_{$table}`";
return $this->db()->query($sql);
}
Исходная таблица здесь обновляется на основе полей формы, которые существуют на заданной формы, которые могут быть добавлены, удалены из или переименованный в в любой момент. Новая таблица также должна соответствовать этим изменениям.
UPDATE: Рабочий раствор следующим образом:
public function updateTableSchema($table, $fields)
{
// Drop the temporary table if exists
$sql = "
DROP TABLE IF EXISTS `temp_{$table}`
";
if (!$this->db()->query($sql)) return FALSE;
// Make a backup of the original table and select the old values into it
$sql = "
CREATE TABLE `temp_{$table}`
SELECT * FROM `$table`
";
if (!$this->db()->query($sql)) return FALSE;
// Drop the old table
if (!$this->db()->query("DROP TABLE `$table`")) return FALSE;
// Recreate the table with the new fields
$sql = "
CREATE TABLE IF NOT EXISTS `$table`
(\n";
$sql .= "`id` int(11) NOT NULL AUTO_INCREMENT,\n";
foreach ($fields as $field)
{
$sql .= html_entity_decode("`$field` varchar(255) NOT NULL,\n");
}
$sql .= "PRIMARY KEY (`id`)\n";
$sql .= "
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
";
if (!$this->db()->query($sql)) return FALSE;
// Insert the temporary records into the new table
$sql = "INSERT INTO `$table` (";
foreach ($fields as $field)
{
$sql .= html_entity_decode("`$field`, ");
}
$sql = rtrim($sql, ', ') . ') SELECT ';
foreach ($fields as $field)
{
$sql .= html_entity_decode("`$field`, ");
}
$sql = rtrim($sql, ', ') . " FROM `temp_{$table}`";
try
{
$this->db()->query($sql);
}
catch (error $e)
{
if (preg_match('/Unknown column/', $e->getMessage()))
{
$new_field = utility::getStringBetween($e->getMessage(), "'", "'");
if (!$new_field) return FALSE;
$this->db()->query("TRUNCATE TABLE `$table`");
$key = array_search($new_field, $fields);
$key--;
// Check if adding after
if ($key > 0)
{
$sql = "
ALTER TABLE `temp_{$table}`
ADD `$new_field` VARCHAR(255) NOT NULL AFTER `{$fields[$key]}`
";
if (!$this->db()->query($sql)) return FALSE;
}
// Check if adding before
else
{
$sql = "
ALTER TABLE `temp_{$table}`
ADD `$new_field` VARCHAR(255) NOT NULL FIRST
";
if (!$this->db()->query($sql)) return FALSE;
}
// Insert the temporary records into the new table
$sql = "INSERT INTO `$table` (";
foreach ($fields as $field)
{
$sql .= html_entity_decode("`$field`, ");
}
$sql = rtrim($sql, ', ') . ') SELECT ';
foreach ($fields as $field)
{
$sql .= html_entity_decode("`$field`, ");
}
$sql = rtrim($sql, ', ') . " FROM `temp_{$table}`";
if (!$this->db()->query($sql)) return FALSE;
}
}
// Drop the temporary table
$sql = "DROP TABLE `temp_{$table}`";
return $this->db()->query($sql);
}
69 % довольно приличный, я не вижу проблемы? – RobertPitt 2010-11-23 18:32:07
едва может видеть в сером цвете, зеленый лучше – ajreal 2010-11-23 18:44:03