deleteしたレコードが再登録できない - PHPプロ!Q&A掲示板

2685

  • 0P

deleteしたレコードが再登録できない

質問日時 / 2010年4月19日 12:13    回答数 / 9件

Questioner:  tsd844u  このエントリーをはてなブックマークに追加 

キーワード / delete    mysql   

お世話になります。

php4.0とmysqlで以下の画面を作成しています。

画面A→一覧画面でレコードの削除を行う。
画面B→一覧画面から別画面を起動しデータ登録を行う。
それぞれの画面でDBへのconnectとcloseを行っています。

レコードAとレコードBを画面Aに表示し、画面AでレコードAを削除し、
その後、画面Bにて、同じ(keyが同じ)レコードAを再度登録しようとすると、
登録できません。特にエラーにもなりません。

レコードBを削除すると、レコードAは、登録できるようになりますが、
レコードBは同様に登録できなくなります。

mysql_querymysql_errorでは特にエラーは返ってきていません。
phpmyadminでinsert文を実行すると作成できます。

ロックの関係かと思い、画面Aで削除後に、明示的にcommitしてみましたが、
変わりませんでした。

どなたか、解決方法をご存知の方ご教授いただけないでしょうか?
よろしくお願い致します。


ツリー一覧

┗A01shimixエラーが返っていないということですが「登録できない
 ┗A01-1tsd844u返信ありがとう御座います。 #phpMyAdminでのテー
  ┣A01-1-1pannna直接の解決方法ではないので的外れかもしれません。
  ┣A01-1-2shimix>includeの数に上限があるのでしょうか? マニュア
  ┣A01-1-3magicflute2登録画面 ins.phpには、INSERT文があるので、ここで登
  ┗A01-1-4tsd844upannnaさん、shimix さん、magicflute2さん、返信あり
   ┣A01-1-4-1shimixそもそも、なぜ登録のonclickにreloadがあるのかわか
   ┗A01-1-4-2pannnaフローというよりURIパラメタの問題でしたか。 だと
    ┗A01-1-4-2-1tsd844ushimixさん、pannnaさん 返信ありがとうございます

回答一覧

並び替え:

A01
answerershimix [4月19日 18:19] (最終編集:4月19日 18:23)

エラーが返っていないということですが「登録できない」のはどうやって確認されていますでしょう。

#phpMyAdminでのテーブル表示か何かでしょうか・・

手元の環境(php5.2.6=さすがにphp4.0は手元にない)で試しましたが再現できません。再現可能なミニマムコードを例示していただけると助かります。

この意見に回答する

ツリーへ TOPへ

A01-1
replyertsd844u [4月20日 11:15]

返信ありがとう御座います。

#phpMyAdminでのテーブル表示か何かでしょうか・・
一覧画面にも出ず、phpMyAdminでもデータが表示されないです。

以下で試しています。ソースをミニマム化していて気づいたのですが、
一覧画面の12行目のincludeをコメントすると起きなくなりました。
呼んでいるファイルの中身というよりは、includeの行数によって起きるように思います。
includeの数に上限があるのでしょうか?

ご確認よろしくお願い致します。



//一覧画面 itiran.php-開始----------------------------------------------
<?php
/* 一覧画面  */
include ("gw.php");
include("include/dbChange.php");
$conn = $dbConnectObj->openConnect();
if (!$conn) {
echo "<Script language=\"JavaScript\">\n"; echo "alert('データベース接続に失敗しました。')\n"; echo "</Script>\n"; exit;}


//↓ここのコメントを外すと発生---------------------------------------------

include ("include/accept.conf");
//include("include/admchk.func");
//include("include/getallemp.func");
//include("include/getalldiv.func");
//include("include/blnk2nbsp.func");
//include("include/getnowtime.func");

//↑--------------------------------------------------------------------

//削除処理
if ($sub == "dele") {
$strSql = "DELETE FROM kozinkyuka  WHERE emp_cd = '$dkey1' AND kyukadatefr = '$dkey2';";
$result = $dbExecObj->exeSql($conn,$strSql);
if(!$result) { echo "削除に失敗しました! " .mysql_error($conn); exit;
}else{ $strSql = "commit "; $resultc = $dbExecObj->exeSql($conn,$strSql);}
}

//データを取得し一覧を作成する。
$sqlstr = "SELECT a.emp_cd,a.kyukadatefr,DATE_FORMAT(a.kyukadatefr,'%Y%m%d') as kyukadatefr_day,DATE_FORMAT(a.kyukadateto,'%Y%m%d') as kyukadateto_day ";
$sqlstr .= ",date_format(kyukadatefr,'%T') as kyukadatefr_zikoku,date_format(kyukadateto,'%T') as kyukadateto_zikoku,a.kyukadateto ";
$sqlstr .= ",a.tani,a.value,a.kyuukakb,a.biko ";
$sqlstr .= "FROM kozinkyuka a ";
$sqlstr .= "WHERE a.emp_cd= '" . "9999" . "' ";
$sqlstr .= "AND a.kyukadatefr between '2010/01/01' and '2010/12/31' ";
$sqlstr .= "ORDER BY a.kyukadatefr desc ";

$result = $dbExecObj->exeSql($conn,$sqlstr);
if (!$result){echo "<Script language=\"JavaScript\">\n"; echo "alert('データを取得できません。')\n"; echo "</Script>\n"; exit;}
?>
                          <TABLE WIDTH=760 border="2" cellspacing="1" cellpadding="3">
                            <tr> <TD align="left" colspan="5" bgcolor="#99ccff">
                                  <span class="fWhite12100"><b>テスト一覧</b></span>
                                  <INPUT TYPE="SUBMIT" NAME="INS" VALUE="新規" onClick="javascript:window.open('ins.php','','width=550,height=450,resizable=yes'); return false;">
                                 </TD>
                            </tr>
                            <tr> <Td WIDTH="250" bgcolor="#99ccff" align=center> <span class="fWhite10100">key2</span> </td>
                                 <TD  WIDTH="300" bgcolor="#99ccff" align=center> <span class="fWhite10100">理由</span> </TD>
                                 <TD bgcolor="#99ccff" align=center> <span class="fRed10100">削</span> </TD>
                            </tr>
<?
$count = $dbExecObj->getNumRows($result);
for ($i = 0; $i < $count; $i++)
{
$kyukadatefr = $dbExecObj->getResult($result, $i, "kyukadatefr_day");
$kyukadatefr_zikoku = $dbExecObj->getResult($result, $i, "kyukadatefr_zikoku");
$kyukadatefr_key = $kyukadatefr . ' ' . $kyukadatefr_zikoku;
$kyukadateto = $dbExecObj->getResult($result, $i, "kyukadateto_day");
?>
                            <TR>
                              <TD align="center" bgcolor="#ffffcc"><span bgcolor="fBlack10100"><? echo $kyukadatefr_key . "" ?></span></TD>
                              <TD ALIGN="left" bgcolor="#ffffcc"><span class="fBlack10100"><? echo $dbExecObj->getResult($result, $i, "biko") ?></span></TD>
                              <td align="center" bgcolor="#ffffcc">
                                  <A class="usually" HREF="itiran.php?sub=dele&dkey1=<?echo $dbExecObj->getResult($result, $i, "emp_cd");?>&dkey2=<?echo $kyukadatefr_key?>" onClick="return confirm('本当に削除しますか?')"><img src="<?php echo $_ROOT_URL_ ?>images/notedel.gif" border="0" alt="削除"></A>
                              </td>
                            </TR>
<?
}
?>
                          </table>
                          <br>
<?
mysql_close($conn);
?>
//一覧画面 itiran.php--------------------------------------------------

//登録画面 ins.php 開始------------------------------------------------
<?php
include("../gw.php");
require_once($_ROOT_DIR_ . "include/dbChange.php");
$conn = $dbConnectObj->openConnect();
if (!$conn) {
echo "<B>データベース接続に失敗しました。</B><BR>\n";
exit;
}
$strSql = $dbSqlObj->setDateStyleToIso();
$dbExecObj->exeSql($conn,$strSql);
?>
<!-- ↓ 表示ボタンのaction -->
<?
//初期値設定
$errFlg = "0";

//開始日チェックルーチン
if (!$begin_date) {
}else {
if (checkdate(substr($begin_date,5,2),substr($begin_date,8,2),substr($begin_date,0,4))) {
$begin_time = mktime(0, 0, 0, substr($begin_date, 5, 2), substr($begin_date, 8, 2), substr($begin_date, 0, 4));
}
else { $message = '<Font Color="#0000ff"><B>日付の指定が無効です。</B><BR></font>'; exit; }
}
$begin_date = strtotime($begin_date);
$end_date = strtotime($end_date);
?>
<html lang="ja">
<head>
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Content-Script-Type" CONTENT="text/javascript">
<meta http-equiv="Content-type" content="text/html; charset=EUC-JP">
<title>テスト</title>
<link rel="stylesheet" href="<?php echo $_ROOT_URL_ ?>css/text.css" type="text/css">
<link rel="stylesheet" href="<?php echo $_ROOT_URL_ ?>css/bgcolor.css" type="text/css">
</head>

<body>
<table width="550" border="0" cellspacing="0" cellpadding="3">
  <tr> 
    <td align=left colspan="1" class="purple"><span class="fWhite12100"><b>■ 日</b></span></td>
  </tr>
  <tr>
    <td>
      <FORM  action="kyuuka_ins.php" method="POST" >
        <input type=text name='begin_year' value='<? echo date("Y",$begin_date);?>' size=4 maxlength=4><span class="fBlack12100">年</span>
          <select name='begin_month'>
<? /*月のリストを生成*/ for($i=1;$i<13;$i++){if (strlen($i) == 1) {$j = "0" . $i;} else{$j = $i;} print("            <option value=\"$j\""); print(">$j\n");} ?>
          </select>
          <span class="fBlack12100">月</span>
          <select name='begin_day'>
<? /*日のリストを生成*/ for($i=1;$i<32;$i++){if (strlen($i) == 1) {$j = "0" . $i;}  else{$j = $i;} print("            <option value=\"$j\""); print(">$j\n");} ?>
          </select>
          <span class="fBlack12100">日</span>
          <select name='begin_hh'>
<? /*時のリストを生成*/ for($i=8;$i<18;$i++){ if (strlen($i) == 1) {$j = "0" . $i;} else{$j = $i;} print("            <option value=\"$j\""); print(">$j\n");} ?>
          </select>
          <span class="fBlack12100">時</span>
          <select name='begin_mi'>
<? /*分のリストを生成*/ for($i=0;$i<60;$i++){ if(($i%10) == 0 ){ if (strlen($i) == 1) {$j = "0" . $i;} else{$j = $i;} print("            <option value=\"$j\""); print(">$j\n");}} ?>
          </select>
          <span class="fBlack12100">分 ~ </span>
          <select name='end_hh'>
<? /*時のリストを生成*/ for($i=8;$i<18;$i++){ if (strlen($i) == 1) {$j = "0" . $i;} else{$j = $i;} print("            <option value=\"$j\""); print(">$j\n"); }?>
          </select>
          <span class="fBlack12100">時</span>
          <select name='end_mi'>
<? /*分のリストを生成*/ for($i=0;$i<60;$i++){ if(($i%10) == 0 ){ if (strlen($i) == 1) {$j = "0" . $i;} else{$j = $i;} print("            <option value=\"$j\""); print(">$j\n"); }}?>
          </select>
          <span class="fBlack12100">分まで</span>

<? $begin_date = date("Y\/m\/d",$begin_date); $end_date = date("Y\/m\/d",$end_date); ?>
    </td>
  </tr>
</table>
<br>

<? 

$PHP_AUTH_USER = '9999';

//登録------------------------------------------------------------------------
if ($sub == "登録") {
$kyukadatefr = $begin_year . "/" . $begin_month . "/" . $begin_day . " " .$begin_hh . ":" . $begin_mi . ":00";
$kyukadatefrS = strtotime($kyukadatefr);
$kyukadateto = $begin_year . "/" . $begin_month . "/" . $begin_day . " " .$end_hh . ":" .$end_mi . ":00";
$kyukadatetoS = strtotime($kyukadateto);

if ($errFlg == "0"){
$sqlstr = "INSERT INTO `kozinkyuka` VALUES ('$PHP_AUTH_USER','$kyukadatefr','$kyukadateto','$tani','$value','$kyuukakb',substring('$biko',1,100))";
$result = $dbExecObj->exeSql($conn, $sqlstr);
print $sqlstr;
if(!$result){
if(mysql_errno($conn) == 1062){ $message = '<Font Color="#0000ff"><B>同一日時で登録済みです。</B><br></font>'; $errFlg = "1";
}else{ $message = '<Font Color="#0000ff"><B>DB更新でエラーが発生しました。".mysql_error($conn)."</B><br></font>'; $errFlg = "9";}
}
}

if ($errFlg == "0"){ $message = '<Font Color="#0000ff">' . $kyukadatefr . '<B>~ で登録しました。</B><br></font>'; }
}
mysql_close($conn);
//登録-----------------------------------------------------------------------------------
?>
<table><tr><td><? echo $message ?></td></tr></table>
<br>
<INPUT type="reset" value="クリア">
            <INPUT type="submit" name="sub" value="登録" onclick="window.opener.location.reload();" >
            <INPUT type="button" value="閉じる" onClick="window.close()">
</FORM>

<Script Language="JavaScript">
<!--
document.forms[1].schedule.focus();
//-->
</Script>

</body>
//登録画面 ins.php---------------------------------------------------------------------------

この意見に回答する

ツリーへ TOPへ

A01-1-1 満足
replyerpannna [4月20日 20:48] (最終編集:4月20日 20:53)

直接の解決方法ではないので的外れかもしれません。

includeのドキュメントを見る限り、行数でエラーが発生するとは考えにくいかと思います。
includeしている該当のファイルの記述に何か問題があるか、
もしくは記述されている定義や関数などで現象が発生しているということはありませんか?

そもそも、レコードBを削除してレコードAを登録すると可能になる、と書かれていますが、
レコードAが存在するのに同一のキーを持つレコードが登録可能な事自体不可解ではあります
(レコードAとレコードBを削除すればレコードAが登録出来るのなら分かりますが…)。

実行しているクエリをechoなりで出力して、本当に期待されるクエリが実行されているかを
確認したほうがいいかもしれません

この意見に回答する

ツリーへ TOPへ

A01-1-2 満足
replyershimix [4月20日 22:05]

>includeの数に上限があるのでしょうか?

マニュアルにも記載はありませんし過去の経験からも上限があるとは思えません。でもphp4.0の頃に何らかのバグがなかったか・・と言われると自信はありません。

∴ includeしているファイルを結合したものをincludeしてみればわかると思います。

削除や登録時に使う変数の内容が途中で置換されていないかどうか、SQL実行の直前にSQL文の内容を画面もしくはファイルに出力すると何かわかるかもしれません。

この意見に回答する

ツリーへ TOPへ

A01-1-3 満足
replyermagicflute2 [4月21日 01:26]

登録画面 ins.phpには、INSERT文があるので、ここで登録するのでしょう。
でも、<form action>は、kyuuka_ins.phpを指しています。

次に、formからPOSTされ、DB関連の処理を行う際、
if ($sub == "登録") この様に書かれています。
通常、POSTされた後の処理は、if(isset($_POST['***']))の様にするのですが、
全く見当たりません。
多分、register_globalsがOnなのでしょう。
あと、submitボタンのvalue値で、POSTを判断する癖は、やめたほうがいい。

最後に、
<INPUT type="submit" name="sub" value="登録" onclick="window.opener.location.reload();
submitとonclickでのリロード?が共存していますが、動きますか!?(タイミングとか)
(HTMLタグ内に、イベントハンドラを書くのは古い)

以上の事から、
そもそも全体のフローが、期待通りではないと推測します。

この意見に回答する

ツリーへ TOPへ

A01-1-4
replyertsd844u [4月21日 12:14]

pannnaさん、shimix さん、magicflute2さん、返信ありがとうございます。


発行しているSQL等確認したところ問題はありませんでした。
access.logを確認したところ、以下のようにうまくいく時といかない時で
処理順が異なっていました。

登録はできていたが、削除されていたということでのようです。
magicflute2さんご指摘のとおりフローがまずいようです。
PHPを初めWEB画面は不慣れなもので、一般的なことがわかっておらず、
古いソースをまねして作成しているところです。

一覧画面で削除ボタン押下後パラメータで削除の情報を渡しおり、削除後
登録画面で登録しリロードすると、削除の処理が走ってしまうのがまずいように
思います。

親画面をリロードする際パラメータの指定等可能でしょうか?
別途方法がございましたらご教授いただけないでしょうか?

よろしくお願い致します。

--- access.log -----------------------------------------------------------------------
--- 1/2を削除後に登録画面で登録
--- 1/2で登録不可
登録→  127.0.0.1 - 9999 [21/Apr/2010:10:55:04 +0900] "POST /wiz/option/ins.php HTTP/1.1" 200 4617 
リロード→127.0.0.1 - 9999 [21/Apr/2010:10:55:04 +0900] "GET /wiz/itiran.php?sub=dele&dkey1=9999&dkey2=20100102%2008:00:00 HTTP/1.1" 200 5591
     127.0.0.1 - - [21/Apr/2010:10:55:04 +0900] "GET /wiz/images/notedel.gif HTTP/1.1" 304 -



--- 1/3で登録可
リロード→127.0.0.1 - 9999 [21/Apr/2010:10:55:36 +0900] "GET /wiz/itiran.php?sub=dele&dkey1=9999&dkey2=20100102%2008:00:00 HTTP/1.1" 200 6246
     127.0.0.1 - - [21/Apr/2010:10:55:36 +0900] "GET /wiz/images/notedel.gif HTTP/1.1" 304 -
登録→  127.0.0.1 - 9999 [21/Apr/2010:10:55:36 +0900] "POST /wiz/option/ins.php HTTP/1.1" 200 4617


-- 1/2でincludeコメントにして登録可
リロード→127.0.0.1 - 9999 [21/Apr/2010:10:57:28 +0900] "GET /wiz/itiran.php?sub=dele&dkey1=9999&dkey2=20100102%2008:00:00 HTTP/1.1" 200 6901
     127.0.0.1 - - [21/Apr/2010:10:57:28 +0900] "GET /wiz/images/notedel.gif HTTP/1.1" 304 -
登録→  127.0.0.1 - 9999 [21/Apr/2010:10:57:28 +0900] "POST /wiz/option/ins.php HTTP/1.1" 200 4617

--- access.log -----------------------------------------------------------------------

この意見に回答する

ツリーへ TOPへ

A01-1-4-1
replyershimix [4月21日 13:05] (最終編集:4月21日 13:05)

そもそも、なぜ登録のonclickにreloadがあるのかわかりません。また(reload時に再送されるとわかっている)QueryString($_GET)で引き渡す意図も理解できません。最低でも$_POSTにするべきじゃないんでしょうか?そういう前提で設計をやり直した方が結果的に早いと思います。

この意見に回答する

ツリーへ TOPへ

A01-1-4-2
replyerpannna [4月21日 16:36]

フローというよりURIパラメタの問題でしたか。
だとすれば、削除処理終了後に「一覧画面を表示するために必要なパラメタのみ」を
付与したURLにリダイレクトしてあげるのが一番手っ取り早い方法ではありますね。
リダイレクトに関してはheader関数のドキュメントを参考にして下さい。

また、あまり理解が進んでいない場合は1つのphpプログラムファイルで
複数の機能処理をさせるというのは問題が発生した場合に切り分けがやりにくいため
お勧めできません。ファイルを分ける工数なんて微々たるものですし、
手戻りなどの手間を考えれば十分ペイできるかと思います。

shimixさんのレスにもありますように、フローなどを書きながら
「なにか問題があっても困らないように(ここ大事)」設計の見直しをするのも
いいかもしれませんね。

この意見に回答する

ツリーへ TOPへ

A01-1-4-2-1
replyertsd844u [4月22日 08:47]

shimixさん、pannnaさん

返信ありがとうございます。
お手を煩わせて申し訳ございませんでした。

そうですね。
画面のイメージのみ作って、手元にあるソースを
いじりながらですすめていました。
POSTとGET等あまり基本的なことも意識せずに行っ
ていましたし。

設計の見直しからしようと思います。

アドバイスありがとうございました。

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
PHPのHTML埋め込み記述について
 このエントリーをはてなブックマークに追加 
A
$_POST["data"] == "男" ? $val = "checked" : $val = "" ; の意味は以下と同じです。 if($_POST["data"] == "男"){ $val = "checked; } e...

>>続きを読む

kende様のご指摘通り、三項演算子を使用する際には、コードの複雑度などを考慮する必要がありますね。書きやすさと共に可読性も追求したいところですね。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)