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

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

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

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

Q&A

解決済

2回答

5977閲覧

PHP 常識的な採番マスタの使い方を教えてください。番号繰上(更新)と採用の手順を一まとめにする方法

saya24

総合スコア222

PHP

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

0グッド

0クリップ

投稿2019/02/05 10:00

ある業務テーブルのプライマリキーを番号体系にしていて、当該テーブルへのレコード挿入時は逐次、番号管理用の別テーブルから番号を採取(1行しかありません)して これを用いる仕様で考えています。
自分が考えたのは以下コーディングです。

新たに番号管理テーブルで番号を採取する(一つ繰り上げる)処理と、今しがた採取した番号を他テーブルに用いる処理が分かれてしまう以上は、他ユーザが同じ操作をしている場合 相応のリスクが伴うのでは??と危惧していますが 間違いありませんか??

一つのトランザクションにしたところで(以下は一つのトランザクションの認識です...)、次のSELECT文で必ず自分が採取した番号をひいてくるとは限らない、この2ステップの間レコードロックをするようなことをしなければならない、と解釈しています。

これは間違いありませんか?
この2ステップ(星印で囲んだ部分)を一まとまりにしてレコードロックするような記述を、PHPではできるのでしょうか?

PHP

1function initial($BIID) { 2 try { 3 4 //DBへ接続 【php_etc/dbconnect.phpに接続先は書いてあります】 5 $err_stage = "err#051"; 6 $db = new ms0connect(); 7 $conn = $db->dbconnect(); 8 $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 9 $conn->beginTransaction(); 10 11 //☆★☆★ 12 $err_stage = "err#052"; 13 $SQL = "UPDATE ATOZ_FINALSEQ SET FINALSEQ=FINALSEQ + 1 WHERE SYSTEMTYPE='".$BIID."'"; 14 $conn->exec($SQL); 15 16 $err_stage = "err#053"; 17 $SQL = "SELECT TOP 1 FINALSEQ FROM ATOZ_FINALSEQ WHERE SYSTEMTYPE='".$BIID."'"; 18 $stmt=$conn->prepare($SQL); 19 $stmt->execute(); 20 //☆★☆★ 21 22 $row = null; 23 $row = $stmt->fetch(PDO::FETCH_ASSOC); 24 if ($row == null) { 25 $err_stage = "err#054"; 26 throw new Exception(); 27 } else { 28 $appno = substr(strval(1000000000 + $row["FINALSEQ"]),-9); 29 $appno = $BIID.$appno; 30 } 31 32 $err_stage = "err#055"; 33 $SQL = "INSERT ATOZ_PLNROUT 34 SELECT A.BIID, A.ORNO, A.FIN, '".$appno."' AS WID, A.STID, B.STNAME, A.USEDPT, NULL AS ACTOP FROM V_ATOZ_BIROUT A LEFT OUTER JOIN 35 (SELECT STID, MAX(STNAME) AS STNAME FROM V_ATOZ_STAGE GROUP BY STID) B 36 ON B.STID=A.STID WHERE A.BIID='".$BIID."'"; 37 $stmt=$conn->prepare($SQL); 38 $stmt->execute(); 39 40 41 $err_stage = "err#056"; 42 $SQL = "INSERT ATOZ_PLNSTAGE 43 SELECT '".$BIID."' AS BIID, '".$appno."' AS WID, A.STID, A.DPTID, A.STNAME, A.USERID, A.SUB, A.USEEXTCON, A.EXTCON FROM V_ATOZ_STAGE A 44 WHERE A.STID IN (SELECT DISTINCT STID FROM V_ATOZ_BIROUT WHERE BIID='".$BIID."')"; 45 $stmt=$conn->prepare($SQL); 46 $stmt->execute(); 47 48 $conn->commit(); 49 $err_stage = null; 50 51 } catch (PDOException $e) { 52 error_log("### SQL Serverデータ取得失敗 ⇒".$SQL."###".$e->getMessage(),0); 53 } catch (Exception $e) { 54 error_log("### SQL Serverデータ取得失敗 ⇒".$SQL."###".$e->getMessage(),0); 55 } 56 $conn = null; 57 return $err_stage; 58}

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

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

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

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

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

cerfweb

2019/02/05 10:11

プライマリーキーをAUTO_INCREMENTにしない理由はどいうことでしょうか。
m.ts10806

2019/02/05 11:04 編集

細かい表現なのですが「採取」だと“元からあるものをとりにいく“ような意味合いになりますので、界隈でよく使われるご自身もタイトルで使われてるそのまま「採番」のほうが適切かと思いますし、phpに限った話ではないのでこのタイトルでは誤解を招きやすいのではないかなと。
saya24

2019/02/07 08:37

mts10806さん どこかへ追記頂けましたか? このサイトの使い勝手が分かっていないのか見つけられないです...
m.ts10806

2019/02/07 08:42

んん?どのような通知が来ましたか?少なくともこの質問には↑のコメントだけですが
m.ts10806

2019/02/07 09:02

あ、ええ、そうですね。「回答の後半」ですね。言葉足らずでした。 ただ、そちらにコメントいただく前に元々書いてました
guest

回答2

0

ベストアンサー

常識的な採番マスタの使い方を教えてください

何が何でも完璧な連番を作らなければならないという特別の必要がない限り、採番マスタを使わず、IDはデータベースの連番機能に任せる、というのが「常識的」な気がします。

SQL Serverの場合、IDENTITYとして利用可能です(MSDN)。

投稿2019/02/05 10:15

maisumakun

総合スコア145184

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

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

saya24

2019/02/05 10:57

いつもご見解をありがとうございます。 頭がとても固く私の達成したいことに発想を転換できないので、引き続き教えて頂けますでしょうか? メインとなるテーブルに採取されるキーは、同一レコードの関連情報を蓄積するその他周囲テーブルにも格納していく考えです。上のコーディングもそう表していますガ、採取したキーはその他テーブルとのデータ結合用に収め、のちのちのデータ結合を容易にしようと考えています。 こういったことを考えているケースでもDBMS側のキー取得機能に頼るのが一般的でしょうか? 一気に複数のテーブルへINSERTすることなどできない筈・一トランザクションで複数テーブルの一連を紐付けるためのアイテムが必要。そういう場合の考え方を教えて頂けたら非常に助かります!
maisumakun

2019/02/05 10:59

1つ目にinsertしてから、PDO::lastInsertIdでそのIDを取得できます。
saya24

2019/02/05 11:33

ありがとうございます。ご紹介された技術があること、初めて知りました。良い機能のがあるのですね。これを把握した上での回答だったのですかね、皆さん。 <https://teratail.com/questions/68723>で紹介された記事をみる限り、同一トランザクションで取得したIDのようで安心できるようですね(決して「直近」という、誰が取得したかも分からないIDではなく)
guest

0

idを繰り上げるって発想が常識と離れすぎてて意味が分からない。

投稿2019/02/05 10:18

kawax

総合スコア10377

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

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

papinianus

2019/02/05 10:27

回答後の質問はご覧にならない方なので、訪問者に誤解がないようマイナスしました。 idを繰り上げるのではなくauto incrementを自前で実装する話。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問