db_change_field
includes/database.mysql-common.inc, строка 513
- Версии
- 6
db_change_field(&$ret, $table, $field, $field_new, $spec, $keys_new = array())
Меняет определение поля.
ВАЖНО: Чтобы сохранить переносимость базы данных, Вам необходимо явно пересоздать все индексы и первичные ключи, которые используют изменяемое поле.
Это означает, что Вы должны удалить все связанные с этим полем ключи и индексы с помощью db_drop_{primary_key,unique_key,index}()
до того, как вызывать db_change_field()
.
Чтобы пересоздать ключи и индексы, передайте определения ключей в виде дополнительного параметра прямо в функцию db_change_field()
.
Например, предположим у вас есть:
$schema['foo'] = array( 'fields' => array( 'bar' => array( 'type' => 'int', 'not null' => TRUE) ), 'primary key' => array('bar') );
и вы хотите сделать поле foo.bar автоинкрементный, оставив его первичным ключом. Правильная последовательность действий такая:
db_drop_primary_key($ret, 'foo'); db_change_field($ret, 'foo', 'bar', 'bar', array( 'type' => 'serial', 'not null' => TRUE ), array( 'primary key' => array('bar') ) );
Причиной для подобных действий, являются различия в механизмах СУБД:
Для PostgreSQL, изменение определения поля вызывает создание дополнительного нового поля и удаления старого, что вызывает удаление всех индексов, первичных ключей и последовательностей (для автоинкрементных полей), которые используют изменяемое поле.
Для MySQL, все поля типа 'автоинкрементное' должны быть частью хотя бы одного ключа или индекса как только они создаются. Вы не можете использовать db_add_{primary_key,unique_key,index}() для этих целей, потому что команда ALTER TABLE, добавляющее колонку без указания ключа или индекса, не выполнится.
Решение - использовать дополнительный параметр $new_keys
, чтобы создать ключ или индекс одновременно с созданием самого поля.
Вы можете использовать db_add_{primary_key,unique_key,index}() во всех случаях, кроме как преобразования поля в автоинкрементное. Вы можете использовать параметр $new_keys
в любых случаях.
Параметры
$ret
Массив, в который будет добавлен результат запроса.
$table
Name of the table.
$field
Имя изменяемой таблицы.
$field_new
Новое имя для поля (по умолчанию тоже самое, что и $field
, если вы не хотите сменить имя).
$spec
Определение нового поля.
$new_keys
Описание дополнительных ключей и индексов, создаваемых в таблице одновременно с изменением поля. Формат тот же, что и при описании таблицы, но без элемента 'fields'
.
Код
<?php
function db_change_field(&$ret, $table, $field, $field_new, $spec, $keys_new = array()) {
$sql = 'ALTER TABLE {'. $table .'} CHANGE '. $field .' '.
_db_create_field_sql($field_new, _db_process_field($spec));
if (count($keys_new)) {
$sql .= ', ADD '. implode(', ADD ', _db_create_keys_sql($keys_new));
}
$ret[] = update_sql($sql);
}
?>
Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии