dbDelta не створює таблиці


15

Я переглянув багато тем, сторінку кодексу і спробував возитися з багатьма речами, але мій код, схоже, не створює таблиць. І я не в змозі зрозуміти, де я помиляюся. Я перевірив booking_db_version в базі даних, він оновлюється, коли я оновлюю його у файлі.

Ось код

global $booking_db_version;
$booking_db_version = "1.0.0";

function booking_install() {
    global $wpdb;
    global $booking_db_version;
    global $tableprefix;
    $installed_version = get_option('booking_db_option');

    $tableprefix = $wpdb->prefix . 'booking_';

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');

    if ( $installed_version !== $booking_db_version ) {
        /* Create table for packages */
        $packagetable = $tableprefix . 'packages';
        $sql = "create table  $packagetable (
            id mediumint(9) NOT NULL AUTO_INCREMENT, 
            name text NOT NULL, 
            description text NOT NULL, 
            city1 text NOT NULL, 
            city2 text NOT NULL,
            PRIMARY KEY  (id)
        );";
        dbDelta($sql);

        /* Create table for hotels */
        $hoteltable = $tableprefix . 'hotels';
        $sql = "create table $hoteltable (
            id mediumint(9) NOT NULL AUTO_INCREMENT, 
            name text NOT NULL, 
            city text NOT NULL, 
            price decimal(10,2) NOT NULL,
            PRIMARY KEY  (id)
        );";
        dbDelta($sql);

        /* Create table for addons */
        $addontable = $tableprefix . 'addons';
        $sql = "create table $addontable (
            id mediumint(9) NOT NULL AUTO_INCREMENT, 
            name text NOT NULL, 
            addongroup text NOT NULL, 
            price decimal(10,2) NOT NULL,
            PRIMARY KEY  (id)
        );";
        dbDelta($sql);

        /* Create table for addon groups */
        $addongrouptable = $tableprefix . 'addon_groups';
        $sql = "create table $addongrouptable (
            id mediumint(9) NOT NULL AUTO_INCREMENT, 
            name text NOT NULL, 
            perhead text NOT NULL,
            PRIMARY KEY  (id)
        );";
        dbDelta($sql);

        update_option('booking_db_version', $booking_db_version);
    }
}
register_activation_hook(__FILE__, 'booking_install');

Відповіді:


18

З WordPress-кодексу про dbDelta :

Функція dbDelta вивчає поточну структуру таблиці, порівнює її з потрібною структурою таблиці та додає або змінює таблицю за необхідності, тому вона може бути дуже зручною для оновлень (див. Wp-admin / upgrade-schema.php для додаткових прикладів як користуватися dbDelta). Зауважте, що функція dbDelta є досить вибагливою. Наприклад:

  • Ви повинні поставити кожне поле у ​​своєму рядку у своєму операторі SQL.
  • У вас повинно бути два пробіли між словами PRIMARY KEY та визначенням вашого основного ключа.
  • Ви повинні використовувати ключове слово KEY, а не його синонім INDEX, і ви повинні включити принаймні один KEY.
  • Ви не повинні використовувати апострофи або зворотні посилання навколо імен полів.

З цими застереженнями, ось наступні рядки нашої функції, які фактично створюють або оновлюють таблицю. Вам потрібно буде замінити власну структуру таблиці змінною $ sql.

Я змінив ваш sql: "create table $packagetable (

До цього: "CREATE TABLE " . $packagetable . " (

Ось робоча копія вашого коду:

global $booking_db_version;
$booking_db_version = "1.0.0";

function booking_install() {
    global $wpdb;
    global $booking_db_version;
    global $tableprefix;
    $installed_version = get_option('booking_db_option');

    $tableprefix = $wpdb->prefix . 'booking_';

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');

    if ( $installed_version !== $booking_db_version ) {
        // Create table for packages 
        $packagetable = $tableprefix . 'packages';
        $sql = "CREATE TABLE " . $packagetable . " (
            id INT NOT NULL AUTO_INCREMENT, 
            name TEXT NOT NULL, 
            description TEXT NOT NULL, 
            city1 TEXT NOT NULL, 
            city2 TEXT NOT NULL,
            PRIMARY KEY  (id)
        ) ". $charset_collate .";";
        dbDelta($sql);

        // Create table for hotels 
        $hoteltable = $tableprefix . 'hotels';
        $sql = "CREATE TABLE " . $hoteltable . " (
            id mediumint(9) NOT NULL AUTO_INCREMENT, 
            name text NOT NULL, 
            city text NOT NULL, 
            price decimal(10,2) NOT NULL,
            PRIMARY KEY  (id)
        ) ". $charset_collate .";";
        dbDelta($sql);

        // Create table for addons 
        $addontable = $tableprefix . 'addons';
        $sql = "CREATE TABLE " . $addontable . " (
            id mediumint(9) NOT NULL AUTO_INCREMENT, 
            name text NOT NULL, 
            addongroup text NOT NULL, 
            price decimal(10,2) NOT NULL,
            PRIMARY KEY  (id)
        ) ". $charset_collate .";";
        dbDelta($sql);

        // Create table for addon groups 
        $addongrouptable = $tableprefix . 'addon_groups';
        $sql = "CREATE TABLE " . $addongrouptable . " (
            id mediumint(9) NOT NULL AUTO_INCREMENT, 
            name text NOT NULL, 
            perhead text NOT NULL,
            PRIMARY KEY  (id)
        ) ". $charset_collate .";";
        dbDelta($sql);

        update_option('booking_db_version', $booking_db_version);
    }
}
register_activation_hook(__FILE__, 'booking_install');

1
Це спрацювало. Я читав, що dbDelta є вигадливим, але не усвідомлював, що не з великої літери CREATE TABLEвикличе його збій.
mehulved

2
Незважаючи на те, що Wordpress не говорить про це на своїй сторінці кодексу, у останньому рядку у вас не може бути кома. Приклад: PRIMARY KEY (id),. dbDelta насправді говорить, що він створює таблицю, навіть якщо її немає
JoeMoe1984,

1
Для довідки, проблема із комою в кінці PRIMARY KEY (id),- це проблема SQL, а не dbDelta і не WP. Отже, жодної документації немає.
Джеремі

Зауважте, що при створенні декількох запитів dbDelta()ви можете передавати свої SQL як масив, dbDeltaа не dbDeltaокремо викликати кожен запит.
toni_lehtimaki

1

Ви можете спробувати цю функцію :

$table_name = "ratings";

$table_columns = "id INT(6) UNSIGNED AUTO_INCREMENT,
                    rate tinyint(1) NOT NULL,
                    ticket_id bigint(20) NOT NULL,
                    response_id bigint(20) NOT NULL,
                    created_at TIMESTAMP";

$table_keys = "PRIMARY KEY (id),
                    KEY ratings_rate (rate),
                    UNIQUE KEY ratings_response_id (response_id)";

create_table($table_name, $table_columns, $table_keys);

0

Використання 'CREATE TABLE' замість 'create table' вирішило для мене проблему.


0

Окрім усіх важливих моментів, вам слід запустити гачок активації.

Поки ви розробляли свій плагін і писали правильний код, вам все одно потрібно активувати свій плагін, щоб запустити гачок, тому ваша таблиця буде створена, коли плагін активований.


-2

Ключові слова SQL, такі як CREATE TABLE та UPDATE, повинні бути великими літерами. тому змініть рядок створення таблиці на:

"CREATE TABLE " . $packagetable . "( 

і

id mediumint(9) NOT NULL AUTO_INCREMENT,

до:

id MEDIUMINT(9) NOT NULL AUTO_INCREMENT,

або це:

name text NOT NULL, 

до:

name TEXT NOT NULL, 

і так далі


"Ключові слова SQL, як [...], повинні бути великими" . Вибачте, але ні, це неправда.
кайзер

для використання функції dbDelta нам слід використовувати великі регістри. перевірте цю сторінку: codex.wordpress.org/Creating_Tables_with_Plugins
niki

Вибачте, але я не можу прочитати цього ніде в джерелі . Я щось пропустив? Можливо, ви хочете додати приклад міні-плагін до своєї відповіді, який показує, що він не вдається (що хтось може взяти і перевірити) із синтаксисом нижнього обліку?
кайзер

у цьому посиланні: посилання , перший абзац Створення або оновлення таблиці згадує про це питання.
shirin niki

Це вірно лише для CREATE TABLE, CREATE DATABASE, INSERT INTOі UPDATE. Все інше або не використовується у порівнянні з великим регістром, або перетворюється на малі регістри . Ваші пропозиції не дають ефекту.
фуксія
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.