Синтаксис ALTER TABLE для dbDelta?

8 янв. 2013 г., 10:58:33
Просмотры: 15.7K
Голосов: 5

Из-за изменений в базе данных мне нужно изменить таблицу, добавив в нее один столбец, но хотя функция выполняется, таблица не изменяется. Вот код ALTER TABLE, который я написал:

$sql = "ALTER TABLE " . $packagetable . " ADD COLUMN price decimal(14,2) NOT NULL AFTER description;";
dbDelta($sql);

Я не смог найти синтаксис ALTER TABLE для dbDelta в интернете. РЕДАКТИРОВАНО: Посмотрев оператор ALTER TABLE в плагине Gravity Forms, я обновил запрос в одну строку.

2
Комментарии

Синтаксис такой же, как и в общем MySQL, поэтому этот вопрос не специфичен для WordPress. Поищите правильный синтаксис для команды ALTER TABLE в Google

shea shea
8 янв. 2013 г. 11:11:45

MySQL-запрос корректен. Проблема на стороне dbDelta. Следовательно, это запрос WordPress. Я проверил эту команду в консоли MySQL самостоятельно перед тем, как опубликовать её здесь.

mehulved mehulved
8 янв. 2013 г. 11:33:31
Все ответы на вопрос 2
11
17

Вы использовали функцию dbDelta неправильно.

Основная цель этой функции — передача SQL-команды для создания таблицы.

Если таблицы не существует, она будет создана.

Если таблица существует, но не соответствует структуре, она будет изменена до совпадения. Это включает добавление и обновление столбцов, индексов и других аспектов.

Поэтому вам нужно запустить dbDelta и передать SQL для создания таблицы, а не для её изменения.

Смотрите здесь, что говорит Codex о добавлении обновления/изменения таблицы с использованием dbDelta

Но это ещё не всё! Функция dbDelta очень привередлива — вы не можете просто вставить любой SQL-запрос, он должен быть правильно отформатирован.

Вот что говорится в Codex на той же странице:

  1. Каждое поле должно быть на отдельной строке в вашем SQL-запросе.
  2. Между словами PRIMARY KEY и определением первичного ключа должно быть два пробела.
  3. Вы должны использовать ключевое слово KEY вместо его синонима INDEX, и должен быть указан хотя бы один KEY.
  4. Не используйте кавычки или обратные апострофы вокруг названий полей.

И из другого источника:

Функция dbDelta

Как я упоминал ранее в одной из своих статей, функция dbDelta может анализировать текущую структуру таблицы, сравнивать её с желаемой структурой и при необходимости добавлять или изменять таблицу. Это делает её очень удобной для обновлений нашего плагина. Однако, в отличие от многих функций WordPress, dbDelta — самая привередливая и проблемная. Чтобы она работала, необходимо соблюсти несколько условий.

  1. Каждое поле должно быть на отдельной строке в SQL-запросе.
  2. Между словами PRIMARY KEY и определением первичного ключа должно быть два пробела.
  3. Вы должны использовать ключевое слово KEY вместо INDEX и указать хотя бы один KEY.

Эти условия кажутся лёгкими для выполнения, но подождите, пока вы с ними не столкнётесь.

8 янв. 2013 г. 11:23:48
Комментарии

dbDelta() поддерживает добавление и обновление столбцов. Смотрите: http://wordpress.stackexchange.com/q/76926/19726

shea shea
8 янв. 2013 г. 11:37:19

Я не говорил, что это не так, я просто сказал, что его подход был неправильным. Используйте оператор CREATE для таблицы, которую вы хотите, а не ALTER, и dbDelta создаст для вас столбцы и изменит таблицу, пока она не будет соответствовать SQL-запросу

Tom J Nowell Tom J Nowell
8 янв. 2013 г. 11:45:15

Понял. Я даже не знал, что это можно сделать с помощью dbDelta()! +1

shea shea
8 янв. 2013 г. 11:47:38

Итак, я обновил SQL-запрос, чтобы добавить колонку с ценой, но получил ошибку БД о том, что таблица уже существует. Вот сообщение об ошибке WordPress database error: [Table 'wp_booking_packages' already exists] CREATE TABLE wp_booking_packages( id mediumint(9) NOT NULL AUTO_INCREMENT, name text NOT NULL, description text NOT NULL, price decimal(14,2) NOT NULL, city1 text NOT NULL, city2 text NOT NULL, PRIMARY KEY (id) ) и я проверил в консоли MySQL, что колонка всё ещё не существует.

mehulved mehulved
8 янв. 2013 г. 11:53:03

Я обновил свой ответ с более подробной информацией. Если в будущем вы сможете публиковать код с помощью gist, чтобы я мог видеть его целиком? Комментарии обычно нарушают форматирование и переносы строк, что может быть разницей между работающим и неработающим dbDelta в данном случае

Tom J Nowell Tom J Nowell
8 янв. 2013 г. 12:32:45

http://gist.github.com если вы не знакомы с этим сервисом

Tom J Nowell Tom J Nowell
8 янв. 2013 г. 12:36:24

Вот гист https://gist.github.com/4482802

mehulved mehulved
8 янв. 2013 г. 12:39:27

@TomJNowell Что если у меня есть поле в операторе CREATE TABLE с типом данных TEXT, и теперь я хочу изменить тип данных этого поля на BIGINT, в этом случае dbDelta не срабатывает. Есть ли способ это сделать?

IAmDhar IAmDhar
6 апр. 2017 г. 21:49:08

@IAmDhar как я могу преобразовать слово "banana" в число? Я бы задал это как совершенно новый вопрос, вряд ли у кого-то есть ответ, и есть большая вероятность, что это выходит за рамки возможностей dbDelta (dbDelta изменит колонку, но не изменит сами данные)

Tom J Nowell Tom J Nowell
6 апр. 2017 г. 22:52:35

@mehulved проблема здесь может быть в том, что между именем таблицы и открывающей скобкой нет пробела. dbDelta очень чувствителен к таким вещам, убедитесь, что SQL-запрос правильно отформатирован и чист, даже если в стандартном SQL пробел обычно не требуется, все равно добавьте его

Tom J Nowell Tom J Nowell
6 апр. 2017 г. 22:54:26

Спасибо за подсказку о необходимости пробела между именем таблицы и открывающей скобкой. Эта информация как раз помогла мне решить проблему с обновлением таблиц!

sebastian sebastian
5 мая 2019 г. 19:13:19
Показать остальные 6 комментариев
1

Чтобы добавить столбец в таблицу базы данных WordPress, можно использовать $wpdb:

global $wpdb;

$table = $wpdb->prefix . 'my_table';
$sql = "ALTER TABLE `{$table}`
        ADD `new_column` VARCHAR(20) NULL DEFAULT NULL;";

$query_result = $wpdb->query( $sql );

Метод $wpdb->query() возвращает false, если запрос выполнился с ошибкой, согласно документации метода. Поэтому можно написать условие if-else для обработки успешного выполнения или ошибки:

if ( $query_result === false ){
    // произошла ошибка
} else {
    // успех
}

Если нужно добавить новый столбец после определенного столбца, используйте AFTER в запросе:

$sql = "ALTER TABLE `{$table}`
        ADD `new_column` VARCHAR(20) NULL DEFAULT NULL
        AFTER `exist_column`;";

Также можно изменить существующий столбец

$sql = "ALTER TABLE `{$table}`
        MODIFY COLUMN `exist_column` VARCHAR(20) NULL DEFAULT NULL;";

или удалить его

$sql = "ALTER TABLE `{$table}`
        DROP COLUMN `exist_column`;";

Небольшой совет: В PHP внутри двойных кавычек (") можно использовать переменные в фигурных скобках ("foo {$var} bar") или без них ("foo $var bar") для вставки переменных в строку, вместо конкатенации ("foo " . $var . " bar"). В примерах выше я использовал этот способ. Подробнее о парсинге строк в PHP.

11 янв. 2021 г. 18:04:04
Комментарии

возможно, ответ Тома лучше подходит для данной темы, но этот ответ все еще полезен в некоторых сценариях. спасибо!

Dreanmer Dreanmer
31 июл. 2022 г. 18:23:27