【问题标题】:Add new column to wordpress database将新列添加到 wordpress 数据库
【发布时间】:2014-02-15 08:16:01
【问题描述】:

我正在尝试更新我的插件。所以我必须升级mysql_table。但是在尝试新列时,程序会出现异常。

这是我当前的表:

$sql = "CREATE TABLE  {$table_name} (
        say_id             int(11)   not null AUTO_INCREMENT,
        customer_mail      text      not null,
        customer_name  text      not null,
        customer_messagge      text      not null,
        messagge_date_time  datetime  not null,

        PRIMARY KEY (say_id)
        )ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1";

        require_once(ABSPATH . "wp-admin/includes/upgrade.php");
        dbDelta($sql);

现在我在一张表中添加了更多列。我尝试使用 Alter 表,这个工作一次并添加一列,但再次刷新我得到这个错误。

这是我的代码

$wpdb->query("ALTER TABLE wp_customer_say ADD say_state INT(1) NOT NULL DEFAULT 1");

这是我的错误

WordPress 数据库错误:[重复的列名 'say_state'] ALTER TABLE wp_customer_say 添加 say_state INT(1) NOT NULL DEFAULT 1

我看到这个错误,我试试这个;

$query          = $wpdb->query("select * from wp_customer_say");
        $respond        = mysql_num_fields( $query );
        $column_array   = array();

        for($i = 0; $i < $respond ; $i++):
            $column_array[]     = mysql_field_name($query,$i);
        endfor;

        if( !in_array("say_state",$column_array) ):
            $wpdb->query("ALTER TABLE wp_customer_say ADD say_state INT(1) NOT NULL DEFAULT 1");
        endif;

我得到了这个错误。

Warning: mysql_num_fields() expects parameter 1 to be resource, integer given in

请帮忙。谢谢你。 抱歉英语不好。

【问题讨论】:

  • 这是因为您的数据库执行其设计目的...持久性

标签: php mysql sql wordpress


【解决方案1】:
$myCustomer = $wpdb->get_row("SELECT * FROM wp_customer_say");
//Add column if not present.
if(!isset($myCustomer->say_state)){
$wpdb->query("ALTER TABLE wp_customer_say ADD say_state INT(1) NOT NULL DEFAULT '' ");

如果您在数据库中没有记录,此代码将失败。仅当您的数据库中保存了至少一条记录时才有效。

【讨论】:

    【解决方案2】:

    如果列不存在,将新列添加到表中的最佳和正确方法。

    /*@ Add status column if not exist */
    global $wpdb;
    $dbname = $wpdb->dbname;
    
    $marks_table_name = $wpdb->prefix . "wpsp_mark";
    
     $is_status_col = $wpdb->get_results(  "SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS`    WHERE `table_name` = '{$marks_table_name}' AND `TABLE_SCHEMA` = '{$dbname}' AND `COLUMN_NAME` = 'status'"  );
    
    if( empty($is_status_col) ):
        $add_status_column = "ALTER TABLE `{$marks_table_name}` ADD `status` VARCHAR(50) NULL DEFAULT NULL AFTER `attendance`; ";
    
        $wpdb->query( $add_status_column );
    endif;
    

    【讨论】:

    • 这是一个很好的解决方案,主要是因为与已接受的答案 [以及此处实际提出的许多其他答案] 不同,它不会在 debug.log 中生成任何错误。接受的答案 [和许多其他人],生成此错误 WordPress database error Unknown column 'column_name' in 'field list' for query
    【解决方案3】:

    写了一个很好的解决方案,它适用于所有情况

    $check_column = (array) $wpdb->get_results(  "SELECT count(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME = '{$wpdb->prefix}my_table' AND COLUMN_NAME = 'some_name'"  )[0];
    
    $table_name = $wpdb->prefix . 'my_table';
     $check_column = (int) array_shift($check_column);
     if($check_column == 0) {
     $wpdb->query(
        "ALTER TABLE $table_name
           ADD COLUMN `some_name` VARCHAR(55) NOT NULL
          ");
      }
    

    【讨论】:

      【解决方案4】:

      我真的很喜欢Rikesh's option(甚至是赞成!),但我认为为了防止硬编码信息可能会改变,例如来自wp-config.php 文件的$table_prefix,这个选项是一个更安全的选择。

      // Replace `table_name` with the actual table name
      $table = $table_prefix.'table_name';
      
      // And use sprintf to pass the table name
      // Alternatively, you can use $table instead of sprintf, 
      //     if you use double quotes such as shown here
      $myCustomer = $wpdb->get_row( sprintf("SELECT * FROM %s LIMIT 1", $table) );
      
      // If you prefer not using sprintf, make sure you use double quotes
      // $myCustomer = $wpdb->get_row( "SELECT * FROM $table LIMIT 1" );
      
      // Replace "missing_field" by the column you wish to add
      if(!isset($myCustomer->missing_field)) {
          $wpdb->query( sprintf( "ALTER TABLE %s ADD phone2 VARCHAR(255) NOT NULL", $table) );
      
          // Alternate example using variable
          // $wpdb->query( "ALTER TABLE $table ADD phone2 VARCHAR(255) NOT NULL") );
      }
      

      【讨论】:

        【解决方案5】:

        只是想补充一点,有一种比@Amandeep Wadhawan 的回答更好的方法。

        register_activation_hook(__FILE__, 'install_tables');
        function install_tables()
        {
            update_options('my_plugins_current_db_version', 0);  // Replace 0 with whatever your final database version is
            // Code here to create the final version of your database tables
        }
        
        add_action('plugins_loaded', 'update_databases');
        public function update_databases()
        {
            global $wpdb;
            $prefix = $wpdb->prefix;
            $a_table_to_update = $prefix . $a_table_to_update;
        
            $current_version = get_option('my_plugins_current_db_version', 0);
        
            switch($current_version)
            {
                // First update
                case 0:
                    // first update code goes here (alter, new table, whatever)
                    $current_version++;
                case 1:
                    // next update code goes here
                    $current_version++;
            }
        
            update_option('my_plugins_current_db_version', $current_version);
        
        }
        

        您只需确保您的install_tables() 函数将始终创建反映最终版本号的表并将my_plugins_current_db_version 选项设置为最终版本号。

        然后在update_databases() 函数中,您只需确保在每个后续案例之前递增$current_version

        使用此设置,您可以盲目更新,而不必先进行不必要的查询以找出列或表是否存在 - 更少的查询总是一件好事......尤其是当您的更新代码在 @987654326 上触发时@钩子。

        它也更干净,显示了清晰的升级路径,并且只执行必要的更新 - 所以效率更高。

        【讨论】:

          【解决方案6】:

          使用此查询。我只使用 mysql-standred 通过快速查询获取字段名称,这将解决您的问题:

          $row = $wpdb->get_results(  "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
          WHERE table_name = 'wp_customer_say' AND column_name = 'say_state'"  );
          
          if(empty($row)){
             $wpdb->query("ALTER TABLE wp_customer_say ADD say_state INT(1) NOT NULL DEFAULT 1");
          }
          

          【讨论】:

          • 您能否提供查询,以便我检查您的查询中存在什么问题?
          • 正确回答这个问题。其他答案,如果表为空,则会出错。谢谢
          • @MustafaOlkun 但在上面你说它不起作用..其次,在那个“不正确”的答案下你说working :)))
          【解决方案7】:

          您可以使用以下方式检查 WordPress 中是否存在列名,

          $myCustomer = $wpdb->get_row("SELECT * FROM wp_customer_say");
          //Add column if not present.
          if(!isset($myCustomer->say_state)){
              $wpdb->query("ALTER TABLE wp_customer_say ADD say_state INT(1) NOT NULL DEFAULT 1");
          }
          

          【讨论】:

          • 我喜欢这个版本。
          • 干得好,效果很好。我基于此添加了my own answer。基本上只是工作确保我们不会硬编码任何我们不需要的东西。 +1
          • 我喜欢这个.. 谢谢.. +1
          • 不,它并不总是有效!如果表中没有行(例如,新表或空表),它将失败。
          • 为什么这有这么多的赞成票?.. 不使用前缀,也使用“SELECT *”来检查列是否存在 :facepalm: 你应该使用“SELECT count(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '{$wpdb->prefix}customer_say' AND COLUMN_NAME = 'say_state'" 检查列是否存在..
          猜你喜欢
          • 1970-01-01
          • 2011-05-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-15
          • 2012-01-07
          相关资源
          最近更新 更多