teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

4

修正

2017/06/14 05:23

投稿

yambejp
yambejp

スコア117921

answer CHANGED
@@ -69,7 +69,7 @@
69
69
  $params=array_merge($params,$id,$val);
70
70
  print_r($params);
71
71
 
72
-
72
+ $stmt = $mysqli->prepare($sql);
73
-
73
+ call_user_func_array([$stmt, "bind_param"], $params);
74
-
74
+ $stmt->execute();
75
75
  ```

3

修正

2017/06/14 05:23

投稿

yambejp
yambejp

スコア117921

answer CHANGED
@@ -50,19 +50,15 @@
50
50
  その上で使うのは各列の0番目と5番目の要素なのでそこだけ抜け出してSQL文に渡します
51
51
 
52
52
  ```PHP
53
+ $id=[];
54
+ $val=[];
53
- if (($fp = fopen("test.csv", "r")) !== FALSE) {
55
+ if (($fp = fopen("x.csv", "r")) !== FALSE) {
54
56
  while (($row = fgetcsv($fp, 1000, ",")) !== FALSE) {
57
+ $id[]=$row[0];
55
- $rows[]=$row;
58
+ $val[]=$row[5];
56
59
  }
57
60
  fclose($fp);
58
61
  }
59
-
60
- $id=[];
61
- $val=[];
62
- array_walk($rows,function($row) use (&$id,&$val){
63
- $id[]=$row[0];
64
- $val[]=$row[5];
65
- });
66
62
  $prepare_param=implode(",",array_fill(0,count($id),"?"));
67
63
  $sql ="update tbl set data=COALESCE(ELT(";
68
64
  $sql.="FIELD(id,".$prepare_param.")";

2

追記

2017/06/14 05:21

投稿

yambejp
yambejp

スコア117921

answer CHANGED
@@ -27,4 +27,53 @@
27
27
  今回のケースですと以下のようなSQL文1つでできます。
28
28
  ```SQL
29
29
  update tbl set data=COALESCE(ELT(FIELD(id,2,3,5),20,300,50),data);
30
- ```
30
+ ```
31
+
32
+ # fgetcsvの使い方
33
+
34
+ 仮にtest.csvがこうだとします
35
+ ```CSV
36
+ 2,a,b,c,d,20,e,f
37
+ 3,a,b,c,d,300,e,f
38
+ 5,a,b,c,d,50,e,f
39
+ ```
40
+ これを配列として受けるのであればこうします
41
+ ```PHP
42
+ if (($fp = fopen("test.csv", "r")) !== FALSE) {
43
+ while (($row = fgetcsv($fp, 1000, ",")) !== FALSE) {
44
+ $rows[]=$row;
45
+ }
46
+ fclose($fp);
47
+ }
48
+ print_r($rows);
49
+ ```
50
+ その上で使うのは各列の0番目と5番目の要素なのでそこだけ抜け出してSQL文に渡します
51
+
52
+ ```PHP
53
+ if (($fp = fopen("test.csv", "r")) !== FALSE) {
54
+ while (($row = fgetcsv($fp, 1000, ",")) !== FALSE) {
55
+ $rows[]=$row;
56
+ }
57
+ fclose($fp);
58
+ }
59
+
60
+ $id=[];
61
+ $val=[];
62
+ array_walk($rows,function($row) use (&$id,&$val){
63
+ $id[]=$row[0];
64
+ $val[]=$row[5];
65
+ });
66
+ $prepare_param=implode(",",array_fill(0,count($id),"?"));
67
+ $sql ="update tbl set data=COALESCE(ELT(";
68
+ $sql.="FIELD(id,".$prepare_param.")";
69
+ $sql.=",".$prepare_param."),data)";
70
+ print $sql;
71
+
72
+ $params =[str_repeat( 'i', count($id)*2)];
73
+ $params=array_merge($params,$id,$val);
74
+ print_r($params);
75
+
76
+
77
+
78
+
79
+ ```

1

補足

2017/06/14 05:17

投稿

yambejp
yambejp

スコア117921

answer CHANGED
@@ -5,4 +5,26 @@
5
5
  CSVを読み込むには[fgetcsv()](http://jp2.php.net/manual/ja/function.fgetcsv.php)をご利用なさるとよいかと
6
6
 
7
7
  もし1件1件の検証が必要ないならforeachで回すと都度SQLを発行するため効率が悪いです
8
- まとめて流し込むような仕組みに変えたほうが実用的です
8
+ まとめて流し込むような仕組みに変えたほうが実用的です
9
+
10
+ # 補足
11
+
12
+ ```SQL
13
+ create table tbl (id int not null unique key,data int);
14
+ insert into tbl values(1,100),(2,200),(3,300);
15
+ ```
16
+ 上記tblに対して、更新データid=2→data=20、id=3→data=300、id=5→data=50を適用するとき
17
+ id=2は更新され、id=3はデータが同じなので更新されず、id=5は存在しないので更新されません。
18
+ 普通にやると以下のように3つのupdate文が必要です
19
+
20
+ ```SQL
21
+ update tbl set data=20 where id=2;
22
+ update tbl set data=300 where id=3;
23
+ update tbl set data=50 where id=5;
24
+
25
+ ```
26
+ しかSQL文は発行すればするほど無駄がおおく、処理が遅くなります。
27
+ 今回のケースですと以下のようなSQL文1つでできます。
28
+ ```SQL
29
+ update tbl set data=COALESCE(ELT(FIELD(id,2,3,5),20,300,50),data);
30
+ ```