MySQL数据库单单元格更新失效问题求助(附完整代码)
数据表格更新功能异常排查求助
本地基于Codepen示例搭建连接MySQL的数据表格,数据显示正常,但更新功能异常:编辑单元格保存后弹出‘Record successfully updated’提示,但数据库未实际更新,控制台无报错。目前仅尝试更新两列,后续需支持全列修改,附上相关代码求排查建议。
前端代码
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Admin</title> <!-- Bootstrap 5 CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.3.0/font/bootstrap-icons.css"> <link rel="stylesheet" href="style/style.css"> <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script> <script src="https://markcell.github.io/jquery-tabledit/assets/js/tabledit.min.js"></script> </head> <body> <div class="main"> <div class="title-container"> <h1>Aggiornamento Prezzi</h1> <h2> <?= $user_name ?></h2> </div> <div class="users-container"> <h2></h2> <div class="table-responsive"> <div class="position-relative content"> <div class="position-absolute w-100 row" style="z-index: 50;"> <div class="col-6"> <div class="filter-wrapper"> <input type="radio" class="filter-checkbox" name="filter" data-filter="" value="Tutto" checked="checked" /> Tutto <input type="radio" class="filter-checkbox" name="filter" data-filter="Antintrusione" value="Antintrusione" /> Antintrusione <input type="radio" class="filter-checkbox" name="filter" data-filter="Antincendio" value="Antincendio" /> Antincendio </div> </div> </div> </div> <br> <table id="sample_data" class="table table-hover"> <thead> <tr> <th scope="col"> Prodotti ID</th> <th scope="col">Nome Prodotto</th> <th scope="col">Gamma</th> <th scope="col">Alfanumerico</th> <th scope="col">Descrizione</th> <th scope="col">Assorbimento</th> <th scope="col">Icona 1</th> <th scope="col">Icona 2</th> <th scope="col">Icona 3</th> <th scope="col">Icona 4</th> <th scope="col">Icona 5</th> <th scope="col">Immagine</th> <th scope="col">Garanzia</th> <th scope="col">Riparazione</th> <th scope="col">Costo Acquisto</th> <th scope="col">Prezzo Vendita</th> <th scope="col">Stato</th> </tr> </thead> <tbody> <?php $var = @$_POST['ProdottiID'] ; $stmt = $conn->prepare("SELECT * FROM `prodotti`"); $stmt->execute(); $result = $stmt->fetchAll(); foreach ($result as $row) { $ProdottiID = $row['ProdottiID']; $NomeProdotto = $row['NomeProdotto']; $Gamma = $row['Gamma']; $Alfanumerico = $row['Alfanumerico']; $Descrizione = $row['Descrizione']; $Assorbimento = $row['Assorbimento']; $Icona1 = $row['Icona1']; $Icona2 = $row['Icona2']; $Icona3 = $row['Icona3']; $Icona4 = $row['Icona4']; $Icona5 = $row['Icona5']; $Immagine = $row['Immagine']; $Garanzia = $row['Garanzia']; $Riparazione = $row['Riparazione']; $CostoAcquisto = $row['CostoAcquisto']; $PrezzoVendita = $row['PrezzoVendita']; $Stato = $row['Stato']; ?> <tr> <td id="ProdottiID" scope="col"><span class="value"><?= $ProdottiID ?></span><div></div></td> <td id="NomeProdotto" scope="col"><span class="value"><?= $NomeProdotto ?></span><div></div></td> <td scope="col"><span class="value"><?= $Gamma ?></span><div></div></td> <td id="Alfanumerico" scope="col"><span class="value"><?= $Alfanumerico ?></span><div></div></td> <td scope="col"><span class="value"><?= $Descrizione ?></span><div></div></td> <td scope="col"><span class="value"><?= $Assorbimento ?></span><div></div></td> <td scope="col"><span class="value"><?= $Icona1 ?></span><div></div></td> <td scope="col"><span class="value"><?= $Icona2 ?></span><div></div></td> <td scope="col"><span class="value"><?= $Icona3 ?></span><div></div></td> <td scope="col"><span class="value"><?= $Icona4 ?></span><div></div></td> <td scope="col"><span class="value"><?= $Icona5 ?></span><div></div></td> <td scope="col"><span class="value"><?= $Immagine ?></span><div></div></td> <td scope="col"><span class="value"><?= $Garanzia ?></span><div></div></td> <td scope="col"><span class="value"><?= $Riparazione ?></span><div></div></td> <td scope="col"><span class="value"><?= $CostoAcquisto ?></span><div></div></td> <td scope="col"><span class="value"><?= $PrezzoVendita ?></span><div></div></td> <td scope="col"><span class="value"><?= $Stato ?></span><div></div></td> </tr> <?php } ?> </tbody> </table> </div> </div> </div> <script> $('table tbody').on('dblclick', 'td', function(){ var valCell = $(this).find('span').text(); $(this).find('span').hide(); $(this).find('div').show().html('\ <div class="input-group">\ <input type="text" class="form-control" value="'+valCell+'">\ <span class="input-group-btn">\ <button id="save" class="btn btn-default" type="button"><i class="bi bi-check2"></i></button>\ <button id="close" class="btn btn-default" type="button"><i class="bi bi-x-circle"></i></button>\ </span>\ </div>'); $(this).find('input').focus(); $(this).closest('tbody').find('td').not($(this)).each(function(){ $(this).find('span').show(); $(this).find('div').hide(); }); }); $('table').on('click','#close',function(){ $(this).closest('td').find('span.value').show(); $(this).closest('div').hide(); }); $('table').on('click','#close',function(){ $(this).closest('td').find('span.value').show(); $(this).closest('div').hide(); }); $('table').on('click','#save', function(){ var getValueInput = $(this).closest('div').find('input').val(); $(this).closest('td').find('span.value').text(getValueInput); $(this).closest('td').find('span.value').show(); $(this).closest('div').hide(); jQuery.ajax({ url: "conn/action2.php", method: "POST", data: {ProdottiID: $('#ProdottiID').val(), NomeProdotto: $('#NomeProdotto').val(), Alfanumerico: $('#Alfanumerico').val()}, cache: false, success: function(response) { alert("Record successfully updated"); } }); }); </script> </body> </html>
数据库更新PHP代码
<?php //action2.php $NomeProdotto = $_POST['NomeProdotto'] ; $Alfanumerico = $_POST['Alfanumerico']; $ProdottiID = $_POST['ProdottiID']; //You need create a database connection $dbhost = 'localhost'; $dbuser = '11111'; $dbpass = '22222'; $conn = mysqli_connect($dbhost, $dbuser, $dbpass, "lslistini2"); if(! $conn ){ die('Could not connect: ' . mysqli_error()); } $retval = mysqli_query($conn,"UPDATE prodotti SET ProdottiID = '$ProdottiID', NomeProdotto = '$NomeProdotto', Alfanumerico = '$Alfanumerico' WHERE ProdottiID = '$ProdottiID'"); if(! $retval ) { die('Could not update data: ' . mysqli_error()); } echo "Updated data successfully "; mysqli_close($conn); ?>
排查与解决建议
前端核心问题
重复ID导致参数错误:表格每行的
<td>都使用了相同的id(如ProdottiID),ID是全局唯一标识,$('#ProdottiID').val()只会获取第一行数据,导致更新时传错ID和字段值。
修复方案:- 将HTML中重复的
id改为class,比如<td class="prodotti-id">、<td class="nome-prodotto">、<td class="alfanumerico"> - 修改AJAX获取参数的逻辑,通过点击的按钮定位到当前行,再获取对应字段:
$('table').on('click','#save', function(){ var getValueInput = $(this).closest('div').find('input').val(); var $row = $(this).closest('tr'); $(this).closest('td').find('span.value').text(getValueInput); $(this).closest('td').find('span.value').show(); $(this).closest('div').hide(); jQuery.ajax({ url: "conn/action2.php", method: "POST", data: { ProdottiID: $row.find('.prodotti-id span.value').text(), NomeProdotto: $row.find('.nome-prodotto span.value').text(), Alfanumerico: $row.find('.alfanumerico span.value').text() }, cache: false, success: function(response) { alert(response); } }); });
- 将HTML中重复的
值获取方式错误:
$('#ProdottiID').val()用于获取表单元素的值,但<td>里是span文本元素,应该用.text()获取内容。
后端核心问题
SQL语句冗余+注入风险:UPDATE语句中无需更新
ProdottiID(WHERE条件已经用它定位,主键通常不修改),同时直接拼接POST参数存在严重SQL注入风险,改用预处理语句:$stmt = $conn->prepare("UPDATE prodotti SET NomeProdotto = ?, Alfanumerico = ? WHERE ProdottiID = ?"); $stmt->bind_param("ssi", $NomeProdotto, $Alfanumerico, $ProdottiID); $stmt->execute();错误处理不完善:
mysqli_error()需要传入连接对象,改为mysqli_error($conn)才能正确获取错误;同时添加受影响行数判断,确认是否真的更新了数据:if(mysqli_affected_rows($conn) == 0) { echo "无记录更新(ID不存在或值未变化)"; } else { echo "数据更新成功"; }
调试技巧
- 在AJAX的success回调中打印后端返回的
response,查看实际执行结果 - 打开浏览器开发者工具的Network面板,检查AJAX请求的Form Data,确认参数是否正确
- 在
action2.php开头添加var_dump($_POST);,查看接收的参数是否符合预期
内容的提问来源于stack exchange,提问作者bastiag5
相关产品推荐
相关产品推荐

