回答編集履歴

4

修正

2017/06/14 05:23

投稿

yambejp
yambejp

スコア114775

test CHANGED
@@ -140,11 +140,11 @@
140
140
 
141
141
 
142
142
 
143
+ $stmt = $mysqli->prepare($sql);
143
144
 
145
+ call_user_func_array([$stmt, "bind_param"], $params);
144
146
 
145
-
147
+ $stmt->execute();
146
-
147
-
148
148
 
149
149
  ```
150
150
 

3

修正

2017/06/14 05:23

投稿

yambejp
yambejp

スコア114775

test CHANGED
@@ -102,31 +102,23 @@
102
102
 
103
103
  ```PHP
104
104
 
105
+ $id=[];
106
+
107
+ $val=[];
108
+
105
- if (($fp = fopen("test.csv", "r")) !== FALSE) {
109
+ if (($fp = fopen("x.csv", "r")) !== FALSE) {
106
110
 
107
111
  while (($row = fgetcsv($fp, 1000, ",")) !== FALSE) {
108
112
 
113
+ $id[]=$row[0];
114
+
109
- $rows[]=$row;
115
+ $val[]=$row[5];
110
116
 
111
117
  }
112
118
 
113
119
  fclose($fp);
114
120
 
115
121
  }
116
-
117
-
118
-
119
- $id=[];
120
-
121
- $val=[];
122
-
123
- array_walk($rows,function($row) use (&$id,&$val){
124
-
125
- $id[]=$row[0];
126
-
127
- $val[]=$row[5];
128
-
129
- });
130
122
 
131
123
  $prepare_param=implode(",",array_fill(0,count($id),"?"));
132
124
 

2

追記

2017/06/14 05:21

投稿

yambejp
yambejp

スコア114775

test CHANGED
@@ -57,3 +57,103 @@
57
57
  update tbl set data=COALESCE(ELT(FIELD(id,2,3,5),20,300,50),data);
58
58
 
59
59
  ```
60
+
61
+
62
+
63
+ # fgetcsvの使い方
64
+
65
+
66
+
67
+ 仮にtest.csvがこうだとします
68
+
69
+ ```CSV
70
+
71
+ 2,a,b,c,d,20,e,f
72
+
73
+ 3,a,b,c,d,300,e,f
74
+
75
+ 5,a,b,c,d,50,e,f
76
+
77
+ ```
78
+
79
+ これを配列として受けるのであればこうします
80
+
81
+ ```PHP
82
+
83
+ if (($fp = fopen("test.csv", "r")) !== FALSE) {
84
+
85
+ while (($row = fgetcsv($fp, 1000, ",")) !== FALSE) {
86
+
87
+ $rows[]=$row;
88
+
89
+ }
90
+
91
+ fclose($fp);
92
+
93
+ }
94
+
95
+ print_r($rows);
96
+
97
+ ```
98
+
99
+ その上で使うのは各列の0番目と5番目の要素なのでそこだけ抜け出してSQL文に渡します
100
+
101
+
102
+
103
+ ```PHP
104
+
105
+ if (($fp = fopen("test.csv", "r")) !== FALSE) {
106
+
107
+ while (($row = fgetcsv($fp, 1000, ",")) !== FALSE) {
108
+
109
+ $rows[]=$row;
110
+
111
+ }
112
+
113
+ fclose($fp);
114
+
115
+ }
116
+
117
+
118
+
119
+ $id=[];
120
+
121
+ $val=[];
122
+
123
+ array_walk($rows,function($row) use (&$id,&$val){
124
+
125
+ $id[]=$row[0];
126
+
127
+ $val[]=$row[5];
128
+
129
+ });
130
+
131
+ $prepare_param=implode(",",array_fill(0,count($id),"?"));
132
+
133
+ $sql ="update tbl set data=COALESCE(ELT(";
134
+
135
+ $sql.="FIELD(id,".$prepare_param.")";
136
+
137
+ $sql.=",".$prepare_param."),data)";
138
+
139
+ print $sql;
140
+
141
+
142
+
143
+ $params =[str_repeat( 'i', count($id)*2)];
144
+
145
+ $params=array_merge($params,$id,$val);
146
+
147
+ print_r($params);
148
+
149
+
150
+
151
+
152
+
153
+
154
+
155
+
156
+
157
+ ```
158
+
159
+

1

補足

2017/06/14 05:17

投稿

yambejp
yambejp

スコア114775

test CHANGED
@@ -13,3 +13,47 @@
13
13
  もし1件1件の検証が必要ないならforeachで回すと都度SQLを発行するため効率が悪いです
14
14
 
15
15
  まとめて流し込むような仕組みに変えたほうが実用的です
16
+
17
+
18
+
19
+ # 補足
20
+
21
+
22
+
23
+ ```SQL
24
+
25
+ create table tbl (id int not null unique key,data int);
26
+
27
+ insert into tbl values(1,100),(2,200),(3,300);
28
+
29
+ ```
30
+
31
+ 上記tblに対して、更新データid=2→data=20、id=3→data=300、id=5→data=50を適用するとき
32
+
33
+ id=2は更新され、id=3はデータが同じなので更新されず、id=5は存在しないので更新されません。
34
+
35
+ 普通にやると以下のように3つのupdate文が必要です
36
+
37
+
38
+
39
+ ```SQL
40
+
41
+ update tbl set data=20 where id=2;
42
+
43
+ update tbl set data=300 where id=3;
44
+
45
+ update tbl set data=50 where id=5;
46
+
47
+
48
+
49
+ ```
50
+
51
+ しかSQL文は発行すればするほど無駄がおおく、処理が遅くなります。
52
+
53
+ 今回のケースですと以下のようなSQL文1つでできます。
54
+
55
+ ```SQL
56
+
57
+ update tbl set data=COALESCE(ELT(FIELD(id,2,3,5),20,300,50),data);
58
+
59
+ ```