2016-03-14 105 views
0

要創建一個sqlite3的數據庫,並從PHP外部CSV文件,我跑插入值:導入CSV文件導入的SQLite3從PHP

$db=new SQLite3("QNH.sqlite"); 
$q="CREATE TABLE IF NOT EXISTS QNH(id INTEGER PRIMARY KEY,unixtimeutc INTEGER,stationqnh TEXT)"; 
$db->exec($q);unset($regel);$id=0; 
if(($fp=fopen("QNH.csv","r"))!==false) 
    {while(($regel=fgetcsv($fp,32,","))!==false) 
     {$id++; 
     $q="INSERT INTO QNH VALUES('".$id."','".$regel[0]."','".$regel[1]."')"; 
     $db->exec($q);}} 
$v=fclose($fp);$db->close(); 

它的工作原理...但可笑和unuseably慢,命中60在完成之前秒完成。 只有總計105132加入了733行。 按照這個速度它需要> 143分鐘。 高清做了很多事情。 這顯然不是這樣做的方式。 我知道如何創建數據庫並在SQLite3命令提示符處導入CSV文件,這在幾秒鐘內就可以工作,但我需要從PHP腳本執行此操作。 我到處尋找,但找不到特定於SQLite3和PHP的任何東西。 任何想法?

+2

「我知道如何創建數據庫並在SQLite3命令提示符處導入CSV文件,這在幾秒鐘內就可以工作」您可以從php – 2016-03-14 22:52:33

+0

調用命令提示符您也可以執行多次插入,如下所示:http: //sackoverflow.com/questions/1609637/is-it-possible-to-insert-multiple-rows-at-a-time-in-an-sqlite-database(如果這適用於你的用例) –

回答

0

與大多數通用編程語言一樣,PHP可以使用命令行參數使用exec()shell_exec()執行外部程序。這與Python的subprocess.call(),R的os.system(),Java的ProcessBuilder(),Perl的system(),C#和VB.NET的Process.Start()類似。

考慮的.sql文件運行你的sqlite的CSV導入並調用它在PHP:

SQL腳本(保存爲import.sql)

CREATE TABLE IF NOT EXISTS QNH(id INTEGER PRIMARY KEY,unixtimeutc INTEGER,stationqnh TEXT); 
.separator , 
.mode csv 
.import output.csv QNH 

PHP腳本(根據需要調整路徑名)

exec("sqlite3 yourdb.sqlite < import.sql") 
+0

建議解決方案會引發錯誤。它在CREATE行以分號結尾時起作用。 「.mode csv」不是必需的。 – Petoetje59

+0

固定分號。可能需要使用[csv中沒有EOL標記]的未來讀者模式(http://stackoverflow.com/questions/14947916/import-csv-to-sqlite)。好奇,確實追加跑得更快? – Parfait

+0

@Parfait,你能解釋一下PHP腳本,你在哪裏傳遞表名?我可以看到你只給出了數據庫名稱'yourdb.sqlite'。 – Himanshu

0

我實現了殼的想法,因爲它是在執行時間簡單的代碼,快速:

$sql="shell_commands.qsl";$fp=fopen($sql,"w"); 
$v="create table QNH(unixtimeutc integer,stationqnh text);\n"; 
$v.=".separator \",\"\n.import ".$csv." QNH\n.exit";$v=fwrite($fp,$v); 
$v=fclose($fp);$v=shell_exec("sqlite3.exe ".$db."<".$sql); 

正如預期的那樣,這將運行快如手動導入。 我也注意到是的SQLite3的不一致:如「創建」關鍵字可以是大寫,但「分隔符」等無法...

+0

通常,SQL關鍵字(如CREATE和TABLE)不區分大小寫。在shell級別發生的任何事情都不是。 – Manngo

0

我知道一切都太遲了,但你嘗試過用事先準備好的聲明?下面是一個示例:

$elements=file('elements.txt'); 
$db=new PDO('sqlite:elements.sqlite'); 
$sql='CREATE TABLE IF NOT EXISTS elements(number int primary key,element varchar, symbol varchar, grp varchar)'; 
$db->exec($sql); 
$sql='INSERT INTO elements(element,number,symbol,grp) VALUES(?,?,?,?)'; 
$prepared=$db->prepare($sql); 
$headers=array_shift($elements); 
foreach($elements as $element) { 
    $element=explode("\t",trim($element)); 
    $prepared->execute($element); 
} 

預處理語句有助於防止SQL注入,但他們也是在加快執行有用的。

準備允許數據庫在運行之前解釋並計劃查詢。這是需要時間的事情,所以你真的只想做一次。後續的多次執行可以利用這一點。

+0

我會堅持shell的想法,因爲它很簡單,並且按照預期工作得很快,但會嘗試你的方法,以防這可能適用於某些其他項目。 – Petoetje59