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

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

ただいまの
回答率

89.20%

Sqlite3とPHPを使いオートナンバリングした値を即時に得たいのですが…

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,007

jinba

score 106

----------------------
no|家族| 名前 |性別|
----------------------
  1|    1|山田太郎| 男|
----------------------
  2|    1|山田次郎| 男|
----------------------
  3|    1|山田花子| 女|
----------------------
  4|    4|鈴木一郎| 男|
----------------------
  5|    4|鈴木一子| 女|
----------------------

上記のようなテーブルがあり
下記のようなPHPを使い
POSTデータ(namae⇒"佐藤一夫" seibetu⇒"男" namae⇒"佐藤二郎" seibetu⇒"男")
というデータを取得し

----------------------
no|家族| 名前 |性別|
----------------------
  1|    1|山田太郎| 男|
----------------------
  2|    1|山田次郎| 男|
----------------------
  3|    1|山田花子| 女|
----------------------
  4|    4|鈴木一郎| 男|
----------------------
  5|    4|鈴木一子| 女|
----------------------
  6|    6|佐藤一夫| 男|
----------------------
  7|    6|佐藤二郎| 男|
----------------------

というデータベースを作りたいのですが
noはINTEGER PRIMARY KEYでオートナンバリングされています。
家族の紐づけとして初めに登録した行のナンバリング値を取得し
家族カラムに登録したいのですがやり方がわかりません。

変数「$kazoku」「$kazoku2」にオートナンバリングした値「6」を入れる方法を教えてください。


//以下PHPのサンプル文

$dsn = "sqlite:データーベース名";
$pdo = new PDO($dsn);

$sql = "CREATE TABLE IF NOT EXISTS kazoku(no INTEGER PRIMARY KEY , 家族 , 名前 , 性別 )";
$stmt = $pdo->prepare($sql);
$stmt->execute();

$namae = @$_POST['namae'];
$seibetu = @$_POST['seibetu'];

$namae2 = @$_POST['namae2'];
$seibetu2 = @$_POST['seibetu2'];

$sql = "INSERT INTO kazoku(家族 , 名前 , 性別 )
VALUES('$kazoku' , '$namae' , '$seibetu')
,('$kazoku2' , '$namae2' , '$seibetu2')";
$st = $pdo->prepare($sql);
$st->execute();
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

オートインクリメントで挿入されたIDはInsetされるまで決定しないので、一回のSQLでnoと家族に同じ値を挿入することはできません。

$pdo->lastInsertId();
で、その接続で最後にオートインクリメントで挿入されたIDを取得することはできます。

なので挿入と同時に家族を確定させることは諦めて、挿入した後に更新という流れになります。

1.佐藤一夫を[家族]不明(null)のままinsertする
*事前に[家族]にnullを使用できるようにしておく
2.$pdo->lastInsertId();によって佐藤一夫のnoを取得
3.佐藤一夫のnoを使って佐藤一夫の家族をupdateする
4.家族は既に取得されているので佐藤二郎(以降)はinsertと同時に家族を指定

という形ですね。

要件にもよりますが、家族テーブルを別のテーブルにして管理をする方が家族の編集をする時に楽だとは思います。
例えば、佐藤一夫が家族ではなくなり、レコードを削除しなければならなくなった場合、更新の処理が少し大変だったりします。

*それとは別の問題として、現在のコードだとSQLインジェクションし放題(システムの破壊やデータの漏洩が可能)の非常に危険なコードになっています。
・SQLインジェクションは$sqlで指定されるSQL文に直接変数を結合させず、:変数名+executeでの指定またはbindParamまたはbindValueを使うことで回避可能です。
SQLインジェクションについて参考URL
プリペアドステートメントの正しい使い方

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/11/18 18:17

    返答遅れ申し訳ありません

    「idを即時に得る」というのは難しいということに気づかされました。

    ・家族の筆頭がわかる
    ・のちのコードが理解しやすいだろう

    という安直な意見から何か方法は無いかと模索していましたが
    結果、今回に限っては家族の紐づけが出来ればよいだけだったので
    家族カラムには別のユニークIDを設定することにしました。

    あとはコードの安全性も指摘してくださってありがとうございました。
    初心者なので参考になりました。

    キャンセル

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

  • ただいまの回答率 89.20%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる