質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

4055閲覧

SQLiteのmodeコマンドをPHPで実行

wkm

総合スコア18

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

2クリップ

投稿2017/05/29 23:17

編集2017/05/30 02:32

####【概要】
カラム値に変更があった際に、変更されたテーブル内の情報をcsv形式で書き出す。なお公開用として制作。

php内でdbに対してある処理を行ったら、csvに

sql

1.mode csv 2.output csvファイルパス 3select * from テーブル名;

この処理を行うようにしたかったので以下のように記述した所、エラーが出て動きませんでした。

php

1$sql_result = $db->query(".mode csv .output csvファイルパス select * from テーブル名;");

何故でしょうか。
一人で悩んだ結果、modeコマンドはphpから実行できないのではないかという結論に至ったのですがこの考え方で間違いないでしょうか。

ご教授宜しくお願い致します。

####【追記】modeコマンドを使わない場合の記述

下記で問題なく動きました。

php

1$db = new SQLite3('dbパス'); 2$csv_path = 'csvファイルパス'; 3$sql_result = $db->query("SELECT * FROM テーブル名 ORDER BY id ASC"); 4 5$edit = ""; 6while( $data = $sql_result->fetchArray() ) { 7$edit .= "{$data['id']},{$data['name']},{$data['age']},{$data['sex']}\n"; 8} 9 10$fp = fopen($csv_path, 'w'); 11fwrite($fp, $edit); 12fclose($fp); 13 14$db->close();

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

検証してみましたが、$db->exec('.mode csv'); の . のところでシンタックスエラーになりますね。.mode等は、SQL文ではなく、sqlite3コマンドへの命令ではないでしょうか?

代替策としては以下か考えられます。

  1. 標準SQLの組み合わせでデータを取得し、アプリケーションでCSVファイルを書き出す
  2. sqlite3コマンドをsystem関数等で呼び出す

2.についてですが、例えば sqlite.sql 等のファイル名で下記のようなファイルを作り、

SQL

1.mode csv 2.output test.csv 3SELECT * FROM test;

PHPからsystem関数で起動するのです。

PHP

1system('sqlite3 ./data/test.db < sqlite.cmd');

外部に公開するようなスクリプトではお勧めしませんが、手元でバックアップ等の管理に使う程度のスクリプトであれば、シェルスクリプトのような感じで使えるでしょう。
…というか、わざわざPHPにするまでもなくシェルスクリプトで十分という感じではありますが、ご参考までに。

投稿2017/05/30 01:48

ockeghem

総合スコア11701

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wkm

2017/05/30 02:23

ご回答有難う御座います。 やりたいことの詳細としてはカラム値に変更があった際に、csv形式で変更されたテーブル内の情報を書き出すということになります。またこちら手元用ではなく公開用として制作しております故シェルスクリプトは考えておりません。 >> .mode等は、SQL文ではなく、sqlite3コマンドへの命令ではないでしょうか? はい、仰る通りです。なので、PHPによる操作が出来ないのかなと考えておりました。 ただ、もう一人の回答者様に貼って頂いた参考サイトを拝見すると、exec()関数を用いることでSQLiteコマンドの使用が可能。と記述されているので何かしらの方法があるのではないかと考えています。 また少し話がズレてしまいますが、modeコマンドを使用せずにquery()でテーブル情報を引っ張ってきて、fopen→fwriteでcsvに書き込みをすることは問題なく実行できました。 ただ、出来ればmodeコマンドを使っての場合とfopen→fwriteでの場合で処理時間の比較を行いたいです。
guest

0

検証はできていないのですが、「modeコマンドはphpから実行できないのではないか」ということはないと思います。
あくまでSQLite上のSQLコマンドの内の1つですよね?
1つ1つ実行していけば問題なく実行されるはずです。

PHP

1$mode_result = $db->query(".mode csv"); 2$output_result = $db->query(".output csvファイルパス"); 3$select_result = $db->query("select * from テーブル名;");

一度に実行する場合は1つの文毎に「;」で区切ると良いでしょう。

PHP

1$mode_result = $db->query(".mode csv;.output csvファイルパス;select * from テーブル名;"); 2

コメントを受けての追記

下記記事は参考になりますでしょうか。
PHPによるSQLite

.○○はSQLiteコマンドとしてexec()で実行する?

追記2

PHPにおいてexecは「コマンドを実行する」もので今回のようにSQLiteコマンドを実行する場合は、「コメントを受けての追記」の参考記事にあるように実行するコマンドファイル(exeファイル)も指定しなければなりません。
また、SQLiteもSQL文も1つ1つ実行していかなければなりません。

PHPによるSQLiteを参考に書いたサンプルコードにコメントをつけて提示しますので自身の環境にあわせて改修してみてください。
※未検証なのであくまでサンプルとして参考程度にとどめておいてください

PHP

1#sqlite3.exeによりSQLiteコマンドを実行。hogehoge.dbは実際に利用しているDBファイル名になると思います 2#sqlite3.exeもそのまま使えるか分からないのでパス調整してみてください 3 4//モード設定 5echo exec( 'sqlite3.exe hogehoge.db .mode csv' ); 6//出力設定ファイル設定 7echo exec( 'sqlite3.exe hogehoge.db .output csvファイルパス' ); 8 9//DBオープン 10$db = sqlite_open(/**/); 11//SQLを実行 12$sql_result = $db->query("select * from テーブル名;"); 13

※もしかしたらDBオープンしてからexec()を実行した方がいいかもしれませんが組んでから調整してください

投稿2017/05/30 00:10

編集2017/05/30 01:39
m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wkm

2017/05/30 00:17

早速のご連絡有難う御座います。1つの文毎に「;」で区切って実行した所、以下のエラーが出ました。 SQLite3::query(): Unable to prepare statement: 1, near ".": syntax error
m.ts10806

2017/05/30 00:20

1つ1つ実行して結果を受け取った場合はどうなりますか?
m.ts10806

2017/05/30 00:26

参考URL追加しました。 SQL文ではなくあくまで「コマンド」として扱うという感じですね。
wkm

2017/05/30 00:58

一つ一つ実行しても結果は同じでした。 参照URL有難う御座います。記事の通りにprepareしてからexecuteしてみたところ、今度は以下の様なエラーが出ました。 SQLite3::prepare(): Unable to prepare statement: 1, near ".": syntax error
m.ts10806

2017/05/30 01:04

追記にも書いたのですが、 「.○○はSQLiteコマンドとしてexec()で実行する」のではないかと。 SELECT文はprepareでもqueryでも実行はできますが、.modeはコマンドなのでコマンドとして実行させなきゃいけないようです。 「SQLiteコマンド」の項を参照。 対象のコマンドは同項にリンクがあり、「.mode」「.output」も記載されていました。
wkm

2017/05/30 01:18 編集

すみません、見ている所が違っておりました。 $db->exec('.mode csv csvファイルパス select * from テーブル名'); で実行してみましたが、エラーが出ました。 SQLite3::exec(): near ".": syntax error 先程からエラーに「near ".": syntax error」こちらのメッセージが出ていますが、これはどういう意味なのでしょうか。ピリオド周辺で構文ミスがあるよという解釈で良いのでしょうか。
m.ts10806

2017/05/30 01:24

エラーメッセージの理解は間違っていません。 ただ、いえるのは ・文章を区切りなくつなげてはいけません  →日本語でいうと句読点なしに文字を羅列しているようなものです ・「SQLiteコマンド」と「SQL文」を一緒にしてはいけません ということ。 .mode ○○でひとつの文章で「SQLiteコマンド」 .output ○○でひとつの文章で「SQLiteコマンド」 select * from テーブル名でひとつの文章で「SQL文」 「;」で区切るように提案したのは「文章はちゃんとひとつひとつ区切ってね」ということ。 追記したのは「SQLiteコマンドはexec()で実行してSQL文はquery()(またはprepare)で実行してね」といいう意味でした。 別の参考URLを追加して、回答を追記しますので少々お待ちください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問