iT邦幫忙

0

資料庫多重更新

rhmi 2020-05-25 16:42:141214 瀏覽

小弟想做一個能一次更新資料庫裡資料的按鈕
如下是顯示的部分

<?php

while ($row = mysqli_fetch_assoc($result_Worklog) )
{	
    $ID = $row['NO'];
    echo "<tr>";
    echo "<td><input type='checkbox' name='name[]' value='$ID'>".$row["User"]."</td>";
    echo "<td>".$row["Class"]."</td>";
    echo "<td>".$row["DealOrder"]."</td>";
    echo "<td>".$row["Content"]."</td>";
    echo "<td>".$row["Remarks"]."</td>";
    echo "<td>".$row["DOC"]."</td>";
    echo "<td>".$row["ECD"]."</td>";
    echo "<td><input type='text' name='Reply[]'  width=100%></td>";
    echo "</tr>";


}
echo "</table>"	;

echo "<input style='float:right' type = 'Submit' name='Submit' value = '送出' onclick = 'deleteconfirm() '>";
?>

如下是SQL指令與PHP_POST的部分

if(isset($_POST['Submit']))
{	
	$NO = $_POST['name'];
	$Reply = $_POST['Reply'];
	$count = count($_POST['Reply']);

	for($i=0 ; $i<$count ; $i++)
	{
		echo $NO[$i]."</br>";
		echo $Reply[$i]."</br>";
		$sql1=" UPDATE Worklog SET SupervisorReply='$Reply[$i]' WHERE NO = ' $NO[$i] ' ";
		$result = execute_sql($link , $bdname , $sql1);
	}
		
}

在ECHO POST過來的資料可以ECHOhttps://ithelp.ithome.com.tw/upload/images/20200525/20127413kxsUbSp8zw.jpg
但是查看資料庫時發現https://ithelp.ithome.com.tw/upload/images/20200525/20127413LR4Y1gvTsr.jpg
更新的資料跑掉了
請問各位大大該如何解決這個問題

ckp6250 iT邦新手 1 級 ‧ 2020-05-25 16:57:53 檢舉
【一次更新資料庫裡資料】
我建議寫在 stored procedure 裡面,傳參數進去,
不要寫在 php 裡。
rhmi iT邦新手 5 級 ‧ 2020-05-26 09:57:37 檢舉
感謝指點
kyoe iT邦新手 5 級 ‧ 2020-06-09 17:52:28 檢舉
做 checkbox 的 update 建議可以把 id 用 in 來組合就不用跑 for 了

1 個回答

1
浩瀚星空
iT邦超人 1 級 ‧ 2020-05-25 17:34:51
最佳解答

其實看到程式碼就覺得好可怕的寫法。
如果你是用看書學的話,快點把那本書給燒了。
不要再學這10多年前的做法了。

更換一下以下的寫法給你學習一下

if(isset($_POST['Submit']))
{	
    $sql1='';
    foreach($_POST['name'] AS $_key => $NO){
        $Reply = $_POST['Reply'][$_key];
        $sql1.="UPDATE Worklog SET SupervisorReply='".$Reply."' WHERE NO = '".$NO."';";
    }
    echo $sql1;//檢查一下
    $result = execute_sql($link , $bdname , $sql1);
}

SQL,一般我會建議新手盡量先不要學用魔術引號的處理。
所以我會建議先用正規用法。

再來,回來你的問題。其實你的問題最主要的原因是因為checkbox。
input中的checkbox是有選擇才會送資料的用法。
所以會導致你的$i中的key對應不上。未送正確的資料。

你可以直接print_r你的post查看。就可以查到原因。

看更多先前的回應...收起先前的回應...

再加強一些

$sql1.= sprintf("UPDATE Worklog SET SupervisorReply='%s' WHERE NO = '%s';", $Reply, $NO);

可以防止一些有可能會被加入 SQL Injection、binary內容攻擊的可能性。

這招沒辦法防 SQL Injection 喔,要注意一下。

rhmi iT邦新手 5 級 ‧ 2020-05-26 09:47:53 檢舉

星空大你好,小弟是新手沒有錯,我會把這本書燒了的。
照你提供的方法去使用當checkbox全選時是正常的如下https://ithelp.ithome.com.tw/upload/images/20200526/20127413PNBjtTdSKB.jpg

但當我跳著選時發生了一樣的問題https://ithelp.ithome.com.tw/upload/images/20200526/20127413piP8rQ80tQ.jpg
請問有其他解嗎

我就教你簡單的一招好了,都是要從html下手
不過正常我自已是會用javascript來讀取生成物件發送。
而不直接表單發送。只是這招對你可能會比較難一些,先不教你這招

第一招是對應值處理

echo "<td><input type='text' name='Reply[]'  width=100%></td>";

將其上的內容,改為如下

echo "<td><input type="hidden" name='ID[]' value='{$ID}' /><input type='text' name='Reply[]'  width=100%></td>";

然後php的部份只要改成

if(isset($_POST['Submit']))
{	
    $sql1='';
    foreach($_POST['ID'] AS $_key => $NO){
        if(in_array($NO,$_POST['name'])!==FALSE){
            $Reply = $_POST['Reply'][$_key];
        $sql1.="UPDATE Worklog SET SupervisorReply='".$Reply."' WHERE NO = '".$NO."';";
        }        
    }
    echo $sql1;//檢查一下
    $result = execute_sql($link , $bdname , $sql1);
}

不過先說,這招其實並不算是很好的招。
畢竟容易破壞樣板。東西一多其實反而會不好規劃。
可以的話,還是盡快學物件發送資料式。
只是現在直接教你這招,怕你會吸收不了。
等你到一定程度,我再教你。

其實本還想教你另一招,陣列定位值。
其實「name='Reply[]'」可以用「name='Reply[1]'指定索引值。
也可以給與name='Reply[abc]'

指定索引值有個缺點。如你html內只用了一個 name='Reply[100]'
但你php會收到 0~100索引值,共101個元素陣列。會有點討厭。
所以這招就看看就好。

rhmi iT邦新手 5 級 ‧ 2020-05-26 11:25:22 檢舉

感謝大大的指點,我已改為我需要的功能了願大大一生平安。

我要發表回答

立即登入回答