0

我正在寻找一种仅在使用 sqlite3 的 PHP 脚本中尚不存在列时才将列添加到表中的方法。看起来单独的 SQL 在这里无法帮助我,例如

ALTER TABLE items ADD COLUMN IF NOT EXISTS new_col INTEGER;

好吧,我正在考虑像尝试运行查询这样的黑客攻击,如果失败,则得出该列尚不存在的结论:

if ($db->querySingle('SELECT new_col FROM items') === FALSE) {
    // False means the query failed
    $db->exec('ALTER TABLE items ADD COLUMN new_col INTEGER');
}

update_stuff_with_new_column($db);

我想它应该可以工作,但是如果查询由于其他原因(例如,事务正在运行)而失败怎么办?

我可以想到其他一些解决方案,但它们看起来都一样:“如果查询失败,则该列可能不存在,请创建它”。有更好的方法吗?

4

2 回答 2

2

可以CREATE TABLE在表中找到该语句的SQL sqlite_master;您需要对其进行解析以查看是否new_col已定义:

sqlite> create table items (col1, col2);
sqlite> select sql from sqlite_master where type = 'table' and name = 'items';
CREATE TABLE items (col1, col2)
sqlite> alter table items add column new_col;
sqlite> select sql from sqlite_master where type = 'table' and name = 'items';
CREATE TABLE items (col1, col2, new_col)

附录:

查看表中是否已存在列的其他方法包括:

尝试准备 ( sqlite3_prepare_v2) 形式的陈述

select ColumnToCheck from TableToCheck;

看看它是否给出了错误(感谢 Igor Tandetnik!)。

或使用

PRAGMA table_info(myTable)

记录在这里

于 2012-07-04T16:49:39.477 回答
0
php file 
===========
<pre>
<?php


define(DB_USER,'root');
define(DB_PASS,'');
define(DB_NAME,'DATABASENAME');

//Load the class

/* Creating Connection for database where we want to make changes using sql file */

$con = mysql_connect('localhost',DB_USER,DB_PASS) or die ("error in connecting $sitename ");
mysql_select_db(DB_NAME,$con) or die("error in databse selction in $sitename");



/* getting content from sql file where we have updated fields */
$fp= file_get_contents('blank_hotel_version_1.0.sql', true);




/* getting list of create table query from sql file content */

$pattern_gettable = '/CREATE TABLE IF NOT EXISTS (.*?) ;/is';

preg_match_all($pattern_gettable,$fp,$tables);

foreach($tables[0] as $value):
    mysql_query($value,$con) or die(mysql_error());
endforeach;





//exit;


/* getting Database table list */

$tables_db ="*";
if($tables_db == '*')
{
    $tables_db = array();
    $result = mysql_query('SHOW TABLES');
    while($row = mysql_fetch_row($result))
    {
        $tables_db[] = $row[0];
    }
}
else
{
    $tables_db = is_array($tables_db) ? $tables_db : explode(',',$tables_db);
}



foreach($tables_db as $tablename):
     $pattern = "CREATE TABLE IF NOT EXISTS `{$tablename}`";

    foreach($tables[0] as $value):

        if(strpos($value,$pattern)=== false):

        else:

            /*getting columns  list from perticular table query of sql file */

            $pattern_cloumn="/CREATE TABLE IF NOT EXISTS `{$tablename}` \((.*?) PRIMARY KEY/is";
            preg_match_all($pattern_cloumn,$value,$columns);


            /*Replacing comma with # so that while we exploade we can easily make array of columns othere wise it make problem for enum(..) datatype or comment */
            $pattern_cm="/\n/ims";
            $columns[1][0]= preg_replace($pattern_cm,"#",$columns[1][0]);
            $colmn=explode("#",$columns[1][0]);
            array_shift($colmn);


            /*Getting name of columns currently we have columns with sql query like "`id` int(11) not null," and we get column name like 'id' into $columnnames array */
            $columnnames=array();
            foreach($colmn as $cols):
                $pattern = '/`(.*?)`/is';
                preg_match_all($pattern, $cols ,$namecols);

                array_push($columnnames,$namecols[1][0]);
            endforeach;


            /*Getting column names from database table */
            $column_query="SHOW COLUMNS FROM {$tablename}";
            $result_clm=mysql_query($column_query);
            $colum_db_array=array();
            while($row_clm=mysql_fetch_array($result_clm))
            {
                array_push($colum_db_array,$row_clm['Field']);
            }


            foreach($columnnames as $key=>$value_cols)
            {
                /*if column not exists in database table then we add column into table */

                if(!in_array($value_cols,$colum_db_array) && $value_cols!="")
                {

                    if(substr($colmn[$key],strlen($colmn[$key])-2)=="',")
                    {
                        $query_cl="ALTER TABLE {$tablename} ADD ".substr($colmn[$key],0,strlen($colmn[$key])-1);
                    }
                    else
                    {
                        $query_cl="ALTER TABLE {$tablename} ADD ".substr($colmn[$key],0,strlen($colmn[$key])-1);
                    }

                    mysql_query($query_cl) or die(mysql_error());
                }
            }
        endif;


    endforeach;


endforeach;


exit;

?>
</pre>

Sql File 
========
<pre>



-- --------------------------------------------------------

--
-- Table structure for table `advertising`
--

CREATE TABLE IF NOT EXISTS `advertising` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `image` varchar(255) NOT NULL,
  `title_tag` varchar(255) NOT NULL,
  `alt_tag` varchar(255) NOT NULL,
  `d_order` int(11) NOT NULL,
  `is_visible` varchar(11) NOT NULL DEFAULT 'Y',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

--
-- Dumping data for table `advertising`
--


-- --------------------------------------------------------

--
-- Table structure for table `advertising_enquiry`
--

CREATE TABLE IF NOT EXISTS `advertising_enquiry` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `advertising_id` varchar(255) NOT NULL,
  `name` varchar(255) NOT NULL,
  `address` varchar(255) NOT NULL,
  `city` varchar(255) NOT NULL,
  `state` varchar(255) NOT NULL,
  `country` varchar(255) NOT NULL,
  `phone` varchar(255) NOT NULL,
  `mobile` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `website` varchar(255) NOT NULL,
  `enquiry` text NOT NULL,
  `budget` varchar(255) NOT NULL,
  `create_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=15 ;

--
-- Dumping data for table `advertising_enquiry`
--


-- --------------------------------------------------------

--
-- Table structure for table `agents`
--

CREATE TABLE IF NOT EXISTS `agents` (
  `id` int(3) NOT NULL AUTO_INCREMENT,
  `agent_name` varchar(150) NOT NULL,
  `contact` varchar(1000) NOT NULL,
  `cat_id` int(3) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;

--
-- Dumping data for table `agents`
--


-- --------------------------------------------------------

--
-- Table structure for table `amenities`
--

CREATE TABLE IF NOT EXISTS `amenities` (
  `id` int(3) NOT NULL AUTO_INCREMENT,
  `am_name` varchar(200) NOT NULL,
  `type` enum('H','R','RE') DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=234 ;

--
-- Dumping data for table `amenities`
--



</pre>

这可能会帮助你谢谢

于 2013-05-01T07:18:39.527 回答