我们使用PHP脚本从API读取数据。对于每个返回的记录,我们将来自该记录的字段与MSSQL数据库中的数据进行比较。根据这两个字段(字符串)是否匹配,实现了不同的逻辑。
匹配不区分大小写,我们也不关心尾随/前导空格。
//value of $p['organizationName'] = 'Forté Initiative'
$groupNameForMatching = trim(strtolower($p['organizationName']));
//there is a group name in this table = 'Forté Initiative'
$matchCountPrep=$conn->prepare("SELECT COUNT(*) AS MatchCount FROM schema.table WHERE LOWER(LTRIM(RTRIM(GroupName))) = :OrganizationName);
$matchCountPrep->bindParam(":OrganizationName", $groupNameForMatching);
try {
$matchCountPrep->execute();
}
catch (PDOException $matchCountError) {
echo "ERROR: " . $matchCountError->getMessage();
exit();
}
$matchCount=$matchCountPrep->fetchColumn();
此代码可对所有不包含特殊字符的组正常工作。例如:
“国际象棋俱乐部”和“国际象棋俱乐部”匹配,该组的$ matchCount = 1值。
尽管“FortéInitiative”和“FortéInitiative”虽然是相同的字符串,但还是不匹配。我相信这可能是由于用于字符“é”的字符编码。
我没有数据库服务器或实例的管理或dba访问权限。我确实对执行脚本的Web服务器和PHP配置具有管理员访问权限。但是,此脚本将被迁移到另一个Web服务器,在不久的将来我将无权对其进行管理访问。
由于上述原因,我正在寻找一种代码内解决方案。在查询的filter子句中进行比较时,是否可以对两个字符串进行类似编码的方法?
谢谢您的任何建议。这是我第一次在Stack Overflow上发帖,所以请让我知道我的问题是否有所欠缺,我将进行更新。感谢您的帮助!
编辑: 我在另一个站点上获得了指导,这导致我的代码和两个解决方案出现问题。
问题在于strtolower不是多字节安全函数,并且不会保留本机编码。使用重音符的编码时,该编码已损坏。另外,我在错误的假设下进行操作,即字符串比较将区分大小写。实际上,使用strtolower的全部需求并不存在。
解决方案一:使用mb_strtolower代替strtolower。 mb_strtolower成功保留了编码,并且使用此函数时,MSSQL比较的行为符合预期。
解决方案二:修剪空格后比较字符串,但不强迫比较的任何一侧都小写。即使字符串与大小写严格不匹配,查询的filter子句仍会将字符串视为匹配。注意:默认情况下,这是正确的,但并非在所有环境中都正确,这取决于数据库的排序规则。