尝试在数据库中创建新表时出错的是什么?

时间:2020-10-20 作者:Emanuel Schiavoni

我尝试用不同的方式创建表,但总是会遇到相同的错误:“em”;错误您的SQL语法有错误;请查看与MySQL服务器版本对应的手册,以了解在“如果不存在查询,请在WordPress数据库的第1行中创建表”附近使用的正确语法

    require_once( ABSPATH . \'wp-admin/includes/upgrade.php\' );
    
    global $wpdb, $rs_plugin_db_version, $table_name_clientes, $table_name_promociones;
    
    $charset_collate = $wpdb->get_charset_collate();
    
    $wpdb->query(
        "CREATE TABLE IF NOT EXISTS $table_name_clientes (
            id int(11) NOT NULL,
            logo text NOT NULL,
            name text NOT NULL,
            whatsapp text DEFAULT \'\' NOT NULL,
            instagram text DEFAULT \'\' NOT NULL,
            facebook text DEFAULT \'\' NOT NULL,
            PRIMARY KEY  (id)
        ) $charset_collate ENGINE = InnoDB"
    );
    dbDelta();
    
    $wpdb->query(
        "CREATE TABLE IF NOT EXISTS $table_name_promociones (
            id int(11) NOT NULL,
            img text NOT NULL,
            title text NOT NULL,
            content text NOT NULL,
            owner int(11) NOT NULL,
            contact int(11) NOT NULL,
            PRIMARY KEY  (id),
            FOREIGN KEY  (owner) REFERENCES $table_name_clientes(id) ON DELETE CASCADE ON UPDATE CASCADE
        ) $charset_collate ENGINE = InnoDB"
    );
    dbDelta();
在其中一个需要创建外键的表中,如果我没有误解的话,dbDelta()不支持外键,因此我最后一次尝试是使用$wpdb->;查询,但无论是否使用外键,结果都是相同的。

也许我的错误很明显,但老实说我找不到

2 个回复
最合适的回答,由SO网友:Emanuel Schiavoni 整理而成

最后我找到了解决方案,正如我所料,这个错误很愚蠢,只是因为我不知道的某些原因,表的名称必须在函数中强制定义,即使使用全局$。。。这行不通,你必须在里面定义它们。

正确的函数如下所示:

$table_name_clientes = $wpdb->prefix . \'clientes\';
$table_name_promociones = $wpdb->prefix . \'promociones\';

$charset_collate = $wpdb->get_charset_collate();

$sql_clientes = "CREATE TABLE IF NOT EXISTS $table_name_clientes (
    id tinyint NOT NULL,
    logo text NOT NULL,
    name text NOT NULL,
    whatsapp text DEFAULT \'\' NOT NULL,
    instagram text DEFAULT \'\' NOT NULL,
    facebook text DEFAULT \'\' NOT NULL,
    PRIMARY KEY  (id)
) $charset_collate ENGINE = InnoDB;";

$sql_promociones = "CREATE TABLE IF NOT EXISTS $table_name_promociones (
    id tinyint NOT NULL,
    img text NOT NULL,
    title text NOT NULL,
    content text NOT NULL,
    owner tinyint NOT NULL,
    contact tinyint NOT NULL,
    PRIMARY KEY  (id),
    FOREIGN KEY  (owner) REFERENCES $table_name_clientes(id) ON DELETE CASCADE ON UPDATE CASCADE
) $charset_collate ENGINE = InnoDB;";

require_once( ABSPATH . \'wp-admin/includes/upgrade.php\' );
dbDelta( $sql_clientes );
dbDelta( $sql_promociones );

SO网友:Tom J Nowell

这不是创建表的方式dbDelta. dbDelta 应使用SQL语句作为其参数,但问题中的代码不传递任何参数。此外,SQL被传递到wpdb->query, 没有检查或消毒。快速运行PHPC将显示未使用prepare调用的警告。

相反,官方文件https://developer.wordpress.org/reference/functions/dbdelta/ 有以下示例:

global $wpdb;
$table_name = $wpdb->prefix . \'dbdelta_test_001\';
$wpdb_collate = $wpdb->collate;
$sql =
"CREATE TABLE {$table_name} (
    id mediumint(8) unsigned NOT NULL auto_increment ,
    first varchar(255) NULL,
    PRIMARY KEY  (id),
    KEY first (first)
    )
    COLLATE {$wpdb_collate}";
 
require_once(ABSPATH . \'wp-admin/includes/upgrade.php\');
dbDelta( $sql );
然而,请注意dbDeltaextremely特定格式要求。例如,后面必须有2个空格PRIMARY KEY. dbDelta 还将调整现有表以匹配语句,如果不存在,则将创建该表

还请记住,在许多情况下,自定义帖子类型更简单,性能更高。在这种情况下,由于自定义表上没有索引,并且内部WP\\U缓存系统丢失,CPT+分类法在某些情况下可能会更有效