我需要找出sqlite數據庫的主鍵。從字符串中提取數據的最有效方式
給予相同的字符串:使用PHP
CREATE TABLE casting(movieid INTEGER, actorid INTEGER, PRIMARY KEY (movieid, actorid))
什麼會得到一個主鍵陣列的最有效的方法是:
CREATE TABLE cia (name PRIMARY KEY, population INTEGER)
或?
我需要找出sqlite數據庫的主鍵。從字符串中提取數據的最有效方式
給予相同的字符串:使用PHP
CREATE TABLE casting(movieid INTEGER, actorid INTEGER, PRIMARY KEY (movieid, actorid))
什麼會得到一個主鍵陣列的最有效的方法是:
CREATE TABLE cia (name PRIMARY KEY, population INTEGER)
或?
「我需要找到一個SQLite數據庫的主鍵。」 - 如果可以使用數據庫,則可以避免解析sql字符串:
PRAGMA TABLE_INFO()的結果有一個字段pk
,如果字段是表的PRIMARY鍵的一部分,則該字段設置爲1。
$pdo = new PDO('sqlite::memory:');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec('CREATE TABLE cia (name PRIMARY KEY, population INTEGER)');
$pdo->exec('CREATE TABLE casting(movieid INTEGER, actorid INTEGER, PRIMARY KEY (movieid, actorid))');
showPrimary($pdo, 'cia');
showPrimary($pdo, 'casting');
function showPrimary($pdo, $tablename) {
// only an example. I don't care about injections here
echo "primary key for '$tablename'\n";
foreach($pdo->query("PRAGMA TABLE_INFO($tablename)", PDO::FETCH_ASSOC) as $row) {
if ($row['pk']) {
printf(" %s %s PRIMARY\n", $row['name'], $row['type']);
}
}
}
打印
primary key for 'cia'
name PRIMARY
primary key for 'casting'
movieid INTEGER PRIMARY
actorid INTEGER PRIMARY
謝謝,這就是我一直在尋找的 – jcuenod 2010-03-08 14:02:00
像這樣的東西應該這樣做:
<?php
$db = new SQLiteDatabase('dbfilename'))
$q = @$db->query('SHOW KEYS FROM cia WHERE Key_name = "PRIMARY"');
$result = $q->fetch();
var_dump(sqlite_fetch_array($result, SQLITE_BOTH))
?>
更新:如果不支持SHOW KEYS,然後你就可以用SELECT statments的infomration和一些工作。這裏被定義爲提供所有表的索引信息你所能PHP函數想:
/**
* return the list of field in $table
* @param string $table name of the sql table to work on
* @param bool $extended_info if true will return the result of a show field query in a query_to_array fashion
* (indexed by fieldname instead of int if false)
* @return array
*/
function list_table_fields($table,$extended_info=FALSE){
# Try the simple method
if((! $extended_info) && $res = $this->query_to_array("SELECT * FROM $table LIMIT 0,1")){
return array_keys($res[0]);
}else{ # There 's no row in this table so we try an alternate method or we want extended infos
if(! $fields = $this->query_to_array("SELECT sql FROM sqlite_master WHERE type='table' AND name ='$table'"))
return FALSE;
# get fields from the create query
$flds_str = $fields[0]['sql'];
$flds_str = substr($flds_str,strpos($flds_str,'('));
$type = "((?:[a-z]+)\s*(?:\(\s*\d+\s*(?:,\s*\d+\s*)?\))?)?\s*";
$default = '(?:DEFAULT\s+((["\']).*?(?<!\\\\)\\4|[^\s,]+))?\s*';
if(preg_match_all('/(\w+)\s+'.$type.$default.'[^,]*(,|\))/i',$flds_str,$m,PREG_SET_ORDER)){
$key = "PRIMARY|UNIQUE|CHECK";
$null = 'NOT\s*NULL';
$Extra = 'AUTOINCREMENT';
$default = 'DEFAULT\s+((["\'])(.*?)(?<!\\\\)\\2|\S+)';
foreach($m as $v){
list($field,$name,$type,$default) = $v;
# print_r($field);
if(!$extended_info){
$res[] = $name;
continue;
}
$res[$name] = array('Field'=>$name,'Type'=>$type,'Null'=>'YES','Key'=>'','Default'=>$default,'Extra'=>'');
if(preg_match("!($key)!i",$field,$n))
$res[$name]['Key'] = $n[1];
if(preg_match("!($Extra)!i",$field,$n))
$res[$name]['Extra'] = $n[1];
if(preg_match('!(NO)T\s+NULL!i',$field,$n))
$res[$name]['Null'] = $n[1];
}
return $res;
}
return FALSE;
}
}
我不知道您的具體情況的最有效的方法(這可能是一個正則表達式),但是如果你有機會到現場數據庫,最清晰的方式將做一個'SHOW KEYS FROM casting' – 2010-01-17 20:55:17
要添加到Pekka的評論:如果你有權訪問任何數據庫,你可以創建一個臨時表並用SHOW KEYS(我推測)來查詢它。因此:用CREATE TEMPORARY TABLE ...替換CREATE TABLE ...(至少在MySQL中),執行查詢,然後用Pekka的建議查詢表。我應該工作,我相信。 – 2010-01-17 21:02:45
在MySQL上對它進行了測試,並且正如預期的那樣,這確實有效。 – 2010-01-17 21:06:49