fuelPHPで、updateして0件だったら、insertというプログラムを作りたいと思い、
アクションクエリを実行した際の戻り値について調べていたところ、
下記サイトを見つけたのですが、まだわかりません。
http://qiita.com/bonon0/items/f5abeee65edf5ca37758
まず、
updateを実行したとき、int型と書いていますが、それはInsetを実行した戻り値と同様、配列型でその中身がint型なのでしょうか?配列型ではなく単純なint型なのでしょうか?
Insert,delete,updateが失敗したときは、どの形式(配列?なんらかの数値?)で何が戻ってくるのでしょうか?
エラーコードや、エラーメッセージが取得されるのでしょうか?
また、fuelPHPで、ストアドプロシージャ、ストアドファンクションを実行するサンプル(戻り値取得も)などありますでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
PHPのDB操作のお約束として、INSERT、UPDATE、DELETEの戻り値は大抵、直前の操作で影響が及ぼされた行数です。
fuelPHPのコードを読んでみると、まず、
fuelphp-1.7.2/fuel/core/classes/db.phpの中で、
// Query types const SELECT = 1; const INSERT = 2; const UPDATE = 3; const DELETE = 4;
と定義しています。
PDOの利用では
fuelphp-1.7.2/fuel/core/classes/database/pdo/connection.php
if ($type === \DB::SELECT) { 略 } elseif ($type === \DB::INSERT) { // Return a list of insert id and rows created return array( $this->_connection->lastInsertId(), $result->rowCount(), ); } else { // Return the number of rows affected return $result->errorCode() === '00000' ? $result->rowCount() : -1; }
となっていて、UPDATEの場合はelseになりますから
http://php.net/manual/ja/pdostatement.rowcount.php
PDOStatement::rowCount — 直近の SQL ステートメントによって作用した行数を返す
ので、intのみが返るのだと思います。
mysqliの利用では
if ($type === \DB::SELECT) { // Return an iterator of results return new \Database_MySQLi_Result($result, $sql, $as_object); } elseif ($type === \DB::INSERT) { // Return a list of insert id and rows created return array( $this->_connection->insert_id, $this->_connection->affected_rows, ); } else { // Return the number of rows affected return $this->_connection->affected_rows; }
となっていますので、
http://php.net/manual/ja/mysqli.affected-rows.php
mysqli::$affected_rows -- mysqli_affected_rows — 直前の MySQL の操作で変更された行の数を得る
やはり、intのみが返ると思います。
非推奨となったmysqlの利用でも
if ($type === \DB::SELECT) { // Return an iterator of results return new \Database_MySQL_Result($result, $sql, $as_object); } elseif ($type === \DB::INSERT) { // Return a list of insert id and rows created return array( mysql_insert_id($this->_connection), mysql_affected_rows($this->_connection), ); } else { // Return the number of rows affected return mysql_affected_rows($this->_connection); }
http://php.net/manual/ja/function.mysql-affected-rows.php
mysql_affected_rows — 一番最近の操作で変更された行の数を得る
一緒ですね。
これらは
fuelphp-1.7.2/fuel/core/classes/database/query.phpのexecute()内
$result = $db->query($this->_type, $sql, $this->_as_object);
で呼び出されていて、そのあと
return $result;
されるので、つまりUPDATE(とDELETE)の戻り値はintのみです。
INSERTの場合は上記のように
array(int insert_id, int affected_rows)となるようです。
insert_idは
http://php.net/manual/ja/mysqli.insert-id.php
このあたりを見ていただけると分かりますが、
直前のクエリで更新された AUTO_INCREMENT フィールドの値を返します。接続での直前のクエリがない場合や クエリが AUTO_INCREMENT の値を更新しなかった場合は ゼロを返します。
となっています。
Insert,delete,updateが失敗したときは、どの形式(配列?なんらかの数値?)で何が戻ってくるのでしょうか?
エラーコードや、エラーメッセージが取得されるのでしょうか?
mysqliを例にすると、
http://php.net/manual/ja/mysqli.affected-rows.php
正の整数が返された場合、それは変更された行数かあるいは取得された行数を 示します。ゼロが返された場合、それは UPDATE 文でレコードが更新されなかったか WHERE 条件に当てはまる行がなかった、またはクエリが実行されなかったことを 示します。-1 は、クエリがエラーを返したことを示します。
となります。PDOでもUPDATE、DELETEの場合、ステータスコードが正常でない場合はfuelphp側で-1を返すようになっていますね。
さらにコードを読んでみると分かりますが、SQL自体が実行できない場合にはDatabase_Exceptionがthrowされるようです。
ですので、これをcatchしてgetMessage()すれば、問題の内容が確認できるようですね。
投稿2015/04/15 23:46
編集2015/04/16 00:09退会済みユーザー
総合スコア0
0
ベストアンサー
PHPとしては
try { $query = DB::select()->from('○○○'); $query->where('id', 1); $result = $query->excute(); } catch(Database_Exception $e){ //try{}内の処理でDatabase_Exceptionが投げられたらここにくる。PHPの処理は続行される。 echo $e->getMessage(); // ←エラー内容が表示される echo $e->getTraceAsString(); // ←スタックトレースが表示される } catch(ErrorException $e){ //ErrorExceptionが投げられたらこっち : } catch(Exception $e){ //Exceptionが投げられたらこっち }
こういうのがセオリーです。
Database_ExceptionはFuelExceptionを継承していて、FuelExceptionはPHP標準のExceptionを継承しています。
ただ、fuelPHPのフレームワーク自体でtry{}catch(){}しているようなので、エラーの内容を知りたいだけなら特に自前でtry{}catch(){}しなくてもエラーハンドリングすることは出来ますね。
ですからエラーがあった時にフレームワークの処理を停止せずに何か処理を続行したい時などに、自前でtry{}catch(){}を実行することになると思います。
投稿2015/04/17 14:39
退会済みユーザー
総合スコア0
0
行が無かったらinsert、行が有ったらupdate こういう処理を upsert と呼んだりします。
質問内容とは少しずれますが、lucker さんがFuelPHPの戻り値について詳しく書いているので私は簡単に upsert の事を書きましょう。
こういう処理はFuelPHPで結果を受け取らずに、SQL文だけで解決することができます。
まずSQL文です。
テーブル
lang
1CREATE TABLE sample( 2 id int NOT NULL, 3 message Text 4);
挿入+更新クエリ(upsertクエリ)
lang
1WITH updated AS (UPDATE sample SET message='updated!' WHERE id=1 RETURNING *) 2INSERT INTO sample(id, message) SELECT 1, 'inserted!' WHERE NOT EXISTS(SELECT * FROM updated);
この upsert クエリを実行することで、「updateして0件だったらinsert」が実現できます。
upsertクエリを実行すると、1度目はmessageが'inserted!'、idが1の行が挿入され、2度実行するとmessageが'updated!'に書き変わります。
UPDATE文で挿入されたデータをRETURNING句で受け取っています。RETURNING句を使うと更新された行数ではなく、更新された行を受け取ることができます。
WITH句はその結果に updated というエリアス名をつけています。
updatedを参照して、中身が空なら更新対象はなかった、あれば更新対象があったことがわかります。
INSERT文にはSELECT文の結果を挿入する機能があります。
NOT EXISTS句を使ってupdatedの結果が空ならINSERTが実行されるようにしています。
投稿2015/04/17 07:32
総合スコア1591
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/04/17 14:04
2015/04/17 14:19
2015/04/17 14:21
2015/04/17 14:41
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/04/17 14:18
退会済みユーザー
2015/04/17 14:20