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

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

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

INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

PHP

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

2回答

1015閲覧

$POSTで渡した配列データをmysqlのテーブルに一括でinsertできない

bunbun007

総合スコア11

INSERT

INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

PHP

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

2クリップ

投稿2019/01/23 01:21

前提・実現したいこと

フィールド数が多いので、htmlでvalueに配列変数を使って値を保持し、POSTで渡してmysqlのデータベースのテーブルに一括で登録したい
一つ気になることがありまして、テーブルにAUTO_INCREMENTのフィールドがあります。
間違いないのは配列の数もテーブルのフィールドの数も同じです。
数を合わせるため、下記のタグも入れています
<input type="hidden" name="dat[]" value="" />

■■な機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

Column count dosen't match value count at row 1

該当のソースコード

htmlの内容

<td><input type="hidden" name="dat[]" value="" /></td> <td><input maxlength='10' size="6" type="date" name="dat[]" /></td> <td><input maxlength='2' size="1" type="text" name="dat[]" /></td> <td><input maxlength='2' size="1" type="text" name="dat[]" /></td> こんな感じで30個あります。

phpの内容

$dat=$_POST['dat'];

$res = implode( ',', $dat );

$query = "INSERT INTO テーブルA VALUES('$res')";

$result = $mysqli->query($query);

if (!$result) {
print('クエリーが失敗しました。' . $mysqli->error);
$mysqli->close();
exit();
}

$mysqli->close();
$result->close();

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

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

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

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

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

m.ts10806

2019/01/23 01:29

コードはマークダウンのcode機能を利用して提示してください。 回答者が正しくコードを再現確認・調整に利用するために平で提示するのは推奨されていません。
m.ts10806

2019/01/23 01:31

またエラー自体は珍しいものではありません。エラーメッセージで調べたことはありますか? テーブルAのテーブル定義(CREATE文が良)も提示されたほうが的確なアドバイスが得られます。
bunbun007

2019/01/23 09:30

ご意見まことにありがとうございました。 検証不足でした。見直します。
退会済みユーザー

退会済みユーザー

2019/01/26 04:52

AI 項目って NULL(もしくは0)の場合に自動で数値をふるのがMySQLの仕様で、任意の値に設定できないというわけではない
guest

回答2

0

Column count dosen't match value count at row 1

列数が1行目の値の数と一致しません。

これはそのままで、INSERTしようとしている列数とデータ(VALUES)が合致していないことを指します。

$queryという変数にSQLを入れていますが、これが想定通りになっているか確かめましたか?

php

1$dat=$_POST['dat']; 2$res = implode( ',', $dat ); 3$query = "INSERT INTO テーブルA VALUES('$res')"; 4echo $query ;

おそらくこうなっています。
INSERT INTO テーブルA VALUES('1,2,3,4,5・・・(略)')

1つのカラム(テーブル定義上、一番最初のカラム)にしか投入されていません。

テーブルにAUTO_INCREMENTのフィールドがあります。

間違いないのは配列の数もテーブルのフィールドの数も同じです。

であれば、AUTO_INCREMENT(および初期値指定がある)フィールドを除いた全フィールドを指定したINSERT文を作成しないといけません。

フィールド名分からないですが、例えばこんな感じ。

※未検証。構文エラーは避けていますが、そのまま動くものではありません。実装イメージだけもってください。

php

1<?php 2$dat=[1,3,5,6,7,8]; //検証のための仮の値。 3$columns = []; 4$values = []; 5foreach($dat as $dnum=>$dval){ 6 $columns[] = "data".$dnum; 7 $values[] = "'".$mysql->real_escape_string($dval)."'"; 8} 9 10$query = "INSERT INTO テーブルA (".implode(",",$columns).") VALUES(".implode(",",$values).");"; 11 12echo $query; 13// INSERT INTO テーブルA (data0,data1,data2,data3,data4,data5) VALUES('1','3','5','6','7','8');

SQLにPOSTされた情報をそのまま入れるのはNGです。必ずエスケープしてください。
できればPDO使った方がすっきり書けます。

もう1点。(むしろこっちのほうが大事)
既に指摘があるとおり全て配列に突っ込んでいては処理が明確にわけられません。
nameにはきちんと役割をそれぞれ明確に与えた名前をつけるべきです。(もしフィールド名も同じようにマジックナンバーなどつけていれば改めるべき)
何1ついいことはないので、今からでも改善してください。
おそらくこのコードから離れて数ヶ月たったときこのコードを見たときにどこが何をやっているか全て見直さなければ理解できない事態が確実に起きます。
メンテナンス性・可読性の低いコードは低ければ低いほど、不具合が起きる可能性が高くなります。

投稿2019/01/23 01:46

編集2019/01/23 02:28
m.ts10806

総合スコア80850

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

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

bunbun007

2019/01/23 09:28

アドバイス誠にありがとうございました。
m.ts10806

2019/01/23 09:54

私の「もう一点」のところまで読まれたのでしたら別のコメントをしているのはいささか納得いかないですね。 プログラムは囚人ではないのできちんと名前をつけてあげてください。
bunbun007

2019/01/26 01:35

アドバイス誠にありがとうございました。 とりあえず例文をもとにやり直しましたらうまくいきました。 ありがとうございました。 1つ質問をさせてください。 postされるデータがあまりにも多いのでnameに配列をつかって、一括でinsertできないかと考えてこのようなやり方をしました。 皆様のご意見を聞きますと、配列にみんなぶち込むのはナンセンスというご意見でした。 そこで、nameにきちんとした変数名を指定した場合のpostでの受け取り方を間単にするやり方をアドバイスいただけないと思いコメントさせていただきました。 例えば htmlの内容 <td><input maxlength='8' size="6" type="date" name="dat01" /></td> <td><input maxlength='2' size="1" type="text" name="dat02" /></td> <td><input maxlength='2' size="1" type="text" name="dat03" /></td>       ↓ <td><input maxlength='2' size="1" type="text" name="dat30" /></td> こんな感じで30個あります。 phpの内容 ■配列の場合は $dat=$_POST['dat']; この一行で受け取れます ■単なる変数(dat01~dat03)を受けとるためには $dat01 = $_POST[‘dat01’]; $dat02 = $_POST[‘dat02’]; $dat03= $_POST[‘dat03’];      ↓ $dat30= $_POST[‘dat30’]; こんな感じで30個必要なのでしょか 配列のように一行にできますか?(一行とはいわず数行とか) よろしくお願いします。
m.ts10806

2019/01/26 01:46

30と決まってるならforで1から回せば良いのでは。可変変数と合わせればその取得処理だけなら三行程度です。
m.ts10806

2019/01/26 01:47

回答にも書きましたがdat01というnameですら何を指してるのか分からないのでナンセンスですけどね。マジックナンバーは避けるべきです。
bunbun007

2019/01/26 02:36

アドバイスありがとうございます そうしましたらname="namae"、name="address"、name="age"…と30個名前が違う変数の受け取り方を簡単にするにはどうしたらいいですか。 よろしくお願いします
m.ts10806

2019/01/26 03:04 編集

そこは調べるなり考えるなりしません?なんでも教えてでは良くないです。 理論的には連番をforで受けとるのと同じです。 配列をうまく使えばhtml生成もバリデートも取得も登録もできます。 だいぶ前ですが回答に書いたことがあるので頑張って探してみてください
bunbun007

2019/01/26 04:19

分かりました ありがとうございました
guest

0

何でもかんでも一緒くたにdat[]にまとめるというのは
いわゆるクソミソな処理ですね。正直感心しません。
また一つのカラムにカンマで区切って流し込むという仕様は
おおよそSQL的な処理ではありません、かならずデータ毎にカラムは分けてください

とりあえずテーブルの状況がわかりませんが主キーのidとデータカラムのみで
構成されているテーブルなら

PHP

1$query = "INSERT INTO テーブルA(col1) VALUES('$res')"; 2//もしくは 3$query = "INSERT INTO テーブルA VALUES(null,'$res')";

とするところからでしょうか?

それとデータ投入時にはprepareで処理しないとインジェクション問題や
セパレータの競合などが発生しますので、きちんと学習してください

sample

ロジックだけ理解してもらえばいいので今回はエスケープ処理やprepare処理は省略します

PHP

1<form method="get"> 2<input type="text" name="dat[]" value="123"><br> 3<input type="text" name="dat[]" value="abc"><br> 4<input type="text" name="dat[]" value="hoge"><br> 5<input type="submit" value="go"> 6</form> 7<?PHP 8$dat=filter_input(INPUT_GET,"dat",FILTER_DEFAULT,FILTER_REQUIRE_ARRAY); 9$res=implode("','",$dat); 10$sql= "INSERT INTO テーブルA VALUES(null,'{$res}')"; 11print $sql; 12?>

※auto_incrementのカラムが先頭にある前提でnullを与えればカラム数は合うでしょう
逆にあわなければなにか重要な情報を提示していないと推測されるので改めて
テーブル構成と入力データの状況を例示してもらうしかありません

投稿2019/01/23 01:45

編集2019/01/23 10:13
yambejp

総合スコア114843

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

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

bunbun007

2019/01/23 03:05

アドバイス誠にありがとうございます。 一つお尋ねします。 テーブル数が30個ありまして、各テーブルのフィールドは50個くらいある仕様なのですが、html内のnameはやはり、例えばname="dat01"・・・name="dat50"としたほうがいいということでしょうか。配列の方がすっきりするようなきがしますが。 なにしろ、フィールド数が多いので一括で登録、更新ができないかと試行錯誤しております。 なにかよいやり方がございましら是非、ご指導いただきたくよろしくお願い致します
yambejp

2019/01/23 03:14 編集

> 各テーブルのフィールドは50個 implodeの仕方を見る限り、すべてのデータを1カラムに突っ込むような 書き方にしかなっていませんよ 今回のご質問の趣旨が、汎用的に公開するものではなく、個人用で データを一切バリデートする必要もないというのであれば いくらでもやりようはあります。 たとえば全部textareaに一度流し込んでしまえば、連結さえいりません > html内のnameはやはり、例えばname="dat01"・・・name="dat50"としたほうがいい そのとおりです。 理由は簡単で、今回トラブルになっている内容をご自身で解決できないように ぐちゃっとしたデータは検証が非常に難しく、トラブル解消が困難だからです 逆になんでもかんでも自己解決できるのであれば、別にどんなやり方でも 好きにすれば良いと思います
bunbun007

2019/01/23 09:32

アドバイス誠にありがとうござました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問