捐赠者查询功能异常:部分血型/城市查询无结果求助
捐赠者查询功能异常排查与解决方案
问题描述
开发的捐赠者查询功能包含血型、城市下拉列表及提交按钮,预期点击按钮后展示匹配血型和城市的捐赠者信息。PostgreSQL数据库donors表数据充足,涵盖多种血型与6个城市,但存在以下异常:
- 默认显示的6个捐赠者卡片中,明确可见AB-血型、Amman城市的捐赠者,但提交这两个参数时页面显示“No donors found”
- 仅A+血型查询可正常返回结果,其他血型及部分城市查询均失效
相关代码
EJS表单
<!--start search--> <div class="search pt-5 "> <div class="container"> <div class="row justify-content-center"> <div class="searchBox col-11 rounded-3 shadow p-5 position-relative"> <form action="donors" method="post" class="d-flex flex-column flex-xl-row gap-3 text-center"> <div class=" w-100"> <select name="bloodType" class="form-select form-select-lg" required> <option selected hidden style="display:none" value="">Blood Type</option> <option value="A+">A+</option> <option value="A-">A-</option> <option value="B+">B+</option> <option value="B-">B-</option> <option value="O+">O+</option> <option value="O-">O-</option> <option value="AB+">AB+</option> <option value="AB-">AB-</option> </select> </div> <div class=" w-100"> <select name="city" class="form-select form-select-lg" required> <option selected hidden style="display:none" value="">City</option> <option value="amman">Amman</option> <option value="madaba">Madaba</option> <option value="irbid">Irbid</option> <option value="zarqa">Zarqa</option> <option value="mafraq">Mafraq</option> <option value="ajloun">Ajloun</option> </select> </div> <div class=" w-100"> <button class="btn searchBtn fw-bold" type="submit"> <i class="fa-solid fa-magnifying-glass fa-lg"></i> </button> </div> </form> </div> </div> </div> </div> <!--end search--> <!--start Donors--> <div class="container mt-5"> <div class="row justify-content-center"> <% if (donors && donors.length > 0) { %> <% donors.forEach(donor => { %> <div class="col-12 col-sm-6 col-lg-4 mb-4"> <div class="card" style="background-color: #D27878;" data-blood-type-index="<%= donor.blood_type %>"> <div class="card-body"> <h5 class="card-title"><%= donor.full_name %></h5> <p class="card-text">Blood Type: <%= getBloodTypeText(donor.blood_type) %></p> <p class="card-text">City: <%= donor.city_name %></p> <p class="card-text">Phone: <%= donor.phone_number %></p> </div> </div> </div> <% }); %> <% } else { %> <p>No donors found.</p> <% } %> </div> </div>
Node.js辅助函数
const getBloodTypeText = (bloodType) => { const validBloodTypes = ['A+', 'A-', 'B+', 'B-', 'O+', 'O-', 'AB+', 'AB-']; if (validBloodTypes.includes(bloodType)) { return bloodType; } else { return 'Unknown Blood Type'; } };
DONORS POST路由
app.post('/donors', async (req, res) => { try { const { bloodType, city } = req.body; console.log('Blood Type:', bloodType); console.log('City:', city); let query = 'SELECT * FROM donors WHERE city_name = $1'; const params = [city]; if (bloodType) { query += ' AND blood_type = $2'; params.push(bloodType); } const donorsResult = await db.query(query, params); const donors = donorsResult.rows; res.render('donors.ejs', { blood_type: bloodType, city_name: city, donors: donors, getBloodTypeText: getBloodTypeText, getCompatibleBloodTypes: getCompatibleBloodTypes }); } catch (error) { console.error('Error fetching data:', error); res.status(500).send('Internal Server Error'); } });
Donors GET路由
app.get('/donors', async (req, res) => { try { const bloodTypesResult = await db.query('SELECT DISTINCT blood_type FROM donors'); const bloodTypes = bloodTypesResult.rows; const citiesResult = await db.query('SELECT * FROM city'); const cities = citiesResult.rows; const defaultDonorsResult = await db.query('SELECT * FROM donors LIMIT 6'); const defaultDonors = defaultDonorsResult.rows; res.render('donors.ejs', { blood_type: bloodTypes, city: cities, donors: defaultDonors, getBloodTypeText: getBloodTypeText, getCompatibleBloodTypes: getCompatibleBloodTypes }); } catch (error) { console.error('Error fetching data:', error); res.status(500).send('Internal Server Error'); } });
异常原因排查
城市名称大小写不匹配
PostgreSQL默认区分字符串大小写,表单中城市选项的value为小写(如amman),但数据库city_name字段存储的是首字母大写格式(如Amman),导致精确匹配失败。血型参数潜在格式差异
若数据库中blood_type字段存在格式问题(如多余空格、符号错误),会导致除A+外的其他血型匹配失败。
解决方案
方案1:统一城市名称匹配规则(推荐)
修改POST路由的SQL查询,使用不区分大小写的匹配逻辑,避免大小写差异导致的查询失败:
app.post('/donors', async (req, res) => { try { const { bloodType, city } = req.body; console.log('Blood Type:', bloodType); console.log('City:', city); // 使用LOWER()函数实现不区分大小写匹配 let query = 'SELECT * FROM donors WHERE LOWER(city_name) = LOWER($1)'; const params = [city]; if (bloodType) { query += ' AND blood_type = $2'; params.push(bloodType); } const donorsResult = await db.query(query, params); const donors = donorsResult.rows; res.render('donors.ejs', { blood_type: bloodType, city_name: city, donors: donors, getBloodTypeText: getBloodTypeText, getCompatibleBloodTypes: getCompatibleBloodTypes }); } catch (error) { console.error('Error fetching data:', error); res.status(500).send('Internal Server Error'); } });
方案2:修正表单城市选项的value值
将表单中城市选项的value修改为与数据库存储格式一致的首字母大写形式:
<select name="city" class="form-select form-select-lg" required> <option selected hidden style="display:none" value="">City</option> <option value="Amman">Amman</option> <option value="Madaba">Madaba</option> <option value="Irbid">Irbid</option> <option value="Zarqa">Zarqa</option> <option value="Mafraq">Mafraq</option> <option value="Ajloun">Ajloun</option> </select>
方案3:验证数据库血型格式
执行SQL查询验证blood_type字段的存储格式,确保与表单选项值完全一致:
SELECT DISTINCT blood_type FROM donors;
若存在格式差异(如A -、AB_),需批量修正数据库数据或在查询中统一格式。
内容的提问来源于stack exchange,提问作者Software Engineer
相关产品推荐
相关产品推荐

