You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

捐赠者查询功能异常:部分血型/城市查询无结果求助

捐赠者查询功能异常排查与解决方案

问题描述

开发的捐赠者查询功能包含血型、城市下拉列表及提交按钮,预期点击按钮后展示匹配血型和城市的捐赠者信息。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');
  }
});

异常原因排查

  1. 城市名称大小写不匹配
    PostgreSQL默认区分字符串大小写,表单中城市选项的value为小写(如amman),但数据库city_name字段存储的是首字母大写格式(如Amman),导致精确匹配失败。

  2. 血型参数潜在格式差异
    若数据库中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 14:14:54