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

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

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

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

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

Q&A

解決済

3回答

8456閲覧

csvをインポートして、そのデータをupdateする方法について

alkeran

総合スコア29

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

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

0グッド

1クリップ

投稿2017/06/14 01:44

Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in ...
以下のコードを実行したら上記のエラーメッセージが出ました。調べてみたら"mysql"はもう古いので、"mysqli" か "PDO"にしなさいということだと思うのですが、どうしたらいいのかわかりません。
ご教授のほどよろしくお願い致します。
あと、"tb_name"のカラムの"code"と一致する"xxx.csv"の"code($data[0])"の"price($data[5])"をupdateしたいのですが、以下のコードでよろしいでしょうか?

<?php // データベース接続 define("DB_SERVER", "xxx"); //サーバ名 define("DB_USER", "xxx"); //ユーザー名 define("DB_PASS", "xxx"); //パスワード define("DB_NAME", "xxx"); //データベース名 $db_conn = mysql_connect(DB_SERVER, DB_USER, DB_PASS); if (!$db_conn) { die("DB connection failed"); } mysql_query("SET NAMES utf8",$db_conn); $db_current = mysql_select_db(DB_NAME, $db_conn); if (!$db_current) { die ("Can't use currentdb"); } // ファイルを読み込む if(!$rows=file('xxx.csv')) { die("File not found"); } // ファイルを一行づつ処理 foreach($rows as $row) { $row = ereg_replace("\r|\n","",$row); $data = explode( ",", $row ); //カンマ区切りの場合 $query = "SELECT code FROM tb_name WHERE code = '$data[0]';"; $result = mysql_query($query); if (!$result) { die("Select query failed : code = $data[0]"); } if(mysql_num_rows($result)!=0) { $query = "UPDATE tb_name SET price = '$data[5]' WHERE code = '$data[0]';"; $result = mysql_query($query); if (!$result) { die("Update query failed : YJ_code = $data[0]"); } } } mysql_close($db_conn); ?>

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

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

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

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

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

guest

回答3

0

ベストアンサー

データが無ければ無視されるのでデータがあるか確認してからupdateしなくてもいいのでは?
(データがない場合とデータが同じで更新されなかった場合をわけたい主旨だとは思いますが)
また変数をSQL文に直接つなげるのはどうかと思います

CSVを読み込むにはfgetcsv()をご利用なさるとよいかと

もし1件1件の検証が必要ないならforeachで回すと都度SQLを発行するため効率が悪いです
まとめて流し込むような仕組みに変えたほうが実用的です

補足

SQL

1create table tbl (id int not null unique key,data int); 2insert into tbl values(1,100),(2,200),(3,300);

上記tblに対して、更新データid=2→data=20、id=3→data=300、id=5→data=50を適用するとき
id=2は更新され、id=3はデータが同じなので更新されず、id=5は存在しないので更新されません。
普通にやると以下のように3つのupdate文が必要です

SQL

1update tbl set data=20 where id=2; 2update tbl set data=300 where id=3; 3update tbl set data=50 where id=5; 4

しかSQL文は発行すればするほど無駄がおおく、処理が遅くなります。
今回のケースですと以下のようなSQL文1つでできます。

SQL

1update tbl set data=COALESCE(ELT(FIELD(id,2,3,5),20,300,50),data);

fgetcsvの使い方

仮にtest.csvがこうだとします

CSV

12,a,b,c,d,20,e,f 23,a,b,c,d,300,e,f 35,a,b,c,d,50,e,f

これを配列として受けるのであればこうします

PHP

1if (($fp = fopen("test.csv", "r")) !== FALSE) { 2 while (($row = fgetcsv($fp, 1000, ",")) !== FALSE) { 3 $rows[]=$row; 4 } 5 fclose($fp); 6} 7print_r($rows);

その上で使うのは各列の0番目と5番目の要素なのでそこだけ抜け出してSQL文に渡します

PHP

1$id=[]; 2$val=[]; 3if (($fp = fopen("x.csv", "r")) !== FALSE) { 4 while (($row = fgetcsv($fp, 1000, ",")) !== FALSE) { 5 $id[]=$row[0]; 6 $val[]=$row[5]; 7 } 8 fclose($fp); 9} 10$prepare_param=implode(",",array_fill(0,count($id),"?")); 11$sql ="update tbl set data=COALESCE(ELT("; 12$sql.="FIELD(id,".$prepare_param.")"; 13$sql.=",".$prepare_param."),data)"; 14print $sql; 15 16$params =[str_repeat( 'i', count($id)*2)]; 17$params=array_merge($params,$id,$val); 18print_r($params); 19 20$stmt = $mysqli->prepare($sql); 21call_user_func_array([$stmt, "bind_param"], $params); 22$stmt->execute();

投稿2017/06/14 03:07

編集2017/06/14 05:23
yambejp

総合スコア114829

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

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

alkeran

2017/06/14 03:30

効率が悪いというのは、それぞれの"code"の"price"をアップデートすると、大量のデータだと時間がかかるということでしょうか? 詳細を記載せずに申し訳ありませんでしたが、そもそもやりたいことは、元々、”tb_name”のデータベースの中には、商品名とコード(code)と価格(空欄:0)があり、アップロードするcsvデータ(xxx.csv)の価格(price)を上書きしたいのです。コードが一致したら。
yambejp

2017/06/14 03:43

効率について補足をつけておきました。
alkeran

2017/06/14 04:44

csvデータは複数個あり、各社商品の価格を上書きしたいため、更新されないものがあってもよいと考えております。今回のコードは自身で考えたものではないため、詳細を教えて頂ければと思うのですが、変数"$data[num]"はcsvデータの1列目のデータということでしょうか?
yambejp

2017/06/14 05:19

csvを配列に抜き出した後、mysqlに渡すまでの処理を追記しときました
alkeran

2017/06/14 11:35

Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference, value given in ... コードを書いていただきありがとうございました。試してみたら上記のエラーが出ました。あと、ブラウザに以下が表示されましたが、データベースの価格は更新されませんでした。 update tb_name set price=COALESCE(ELT(FIELD(id,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?),?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?),price)Array ( [0] => iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii [1] => 1234565789 [2] => 987654321 [3] => 2468101214 [4] =>...
guest

0

古いというか、PHP 5.5で非推奨となり、PHP7で削除されました。 PHPマニュアル:mysql_connect

記事にもありますが、phpマニュアルを参考にして書き換えると良いです。
基本的には同じですが引数に与える情報や順番が変わってきます。

投稿2017/06/14 02:24

m.ts10806

総合スコア80850

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

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

0

とりあえず、下記の記事を読んでみては如何でしょうか。
[PHP] mysqli使い方まとめ(MySQL接続~SELECT実行まで)

投稿2017/06/14 01:55

coco_bauer

総合スコア6915

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

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

alkeran

2017/06/14 02:29

ありがとうございます。勉強になります。 自分なりに解釈して以下のコードに書き換えました。エラーは出なくなったのですが、updateが上手にできませんでした。 <?php // mysqliクラスのオブジェクトを作成 $mysqli = new mysqli('xxx', 'xxx', 'xxx', 'xxx'); if ($mysqli->connect_error) { echo $mysqli->connect_error; exit(); } else { $mysqli->set_charset("utf8"); } // ファイルを読み込む if(!$rows=file('xxx.csv')) { die("File not found"); } // ファイルを一行づつ処理 foreach($rows as $row) { $row = preg_replace("/\r/", "/\n/","",$row); $data = explode( ",", $row ); //カンマ区切りの場合 $sql = "SELECT code FROM tb_name WHERE code = '$data[0]';"; $result = $mysqli->query($sql); if (!$result) { die("Select query failed : YJ_code = $data[0]"); } if(mysql_num_rows($result)!=0) { $sql = "UPDATE tb_name SET price = '$data[5]' WHERE code = '$data[0]';"; $result = $mysqli->query($sql); if (!$result) { die("Update query failed : code = $data[0]"); } } } $mysqli->close(); ?>
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問