我在使用CCSID作为十六进制值的laravel中从查询返回结果时遇到问题。如果我使用有问题的标识符,并在我的sql客户端中将其手动插入查询中,它将起作用:
FROM TableOne T1
WHERE CAST(T1 . IDENITIFIER AS CHAR(26) CCSID 65535) = x'0213725502A3BC45706AEE6001';
但是,当我在以标识符作为参数的laravel模型中尝试此操作时,它会出错并显示x:identifier而不是x,然后显示字符串:
FROM TableOne T1
WHERE CAST(T1 . IDENITIFIER AS CHAR(26) CCSID 65535) = x':identifier'
";
try {
return DB::connection('odbc')->select($sql, [
'identifier' => $identifier
]);
} catch (Exception $e) {
return false;
}
如何使该参数与x一起正确注入,使其像手动操作一样工作?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在 Laravel 中,当使用参数绑定时,SQL 语句中的占位符(如 :identifier
)会被安全地替换为实际值,并且会自动进行适当的转义以防止 SQL 注入攻击。但是,你的场景中涉及到特殊的字符串格式(例如 x'0213725502A3BC45706AEE6001'
),这需要特殊处理。
为了确保这种特定格式的字符串正确注入到查询中,你不能直接将它作为参数绑定,因为 Laravel 会将其视为普通字符串并添加引号。你需要手动构建这部分 SQL 字符串,同时仍然利用参数绑定来保持其他部分的安全性。
这里是一个修改后的示例代码,展示了如何结合使用直接字符串拼接和参数绑定:
$hexValue = "x'" . bin2hex($identifier) . "'"; // 假设 $identifier 是原始的二进制或十六进制字符串
$sql = "
SELECT *
FROM TableOne T1
WHERE CAST(T1.IDENTIFIER AS CHAR(26) CCSID 65535) = ?
";
try {
return DB::connection('odbc')->select($sql, [$hexValue]);
} catch (Exception $e) {
return false;
}
在这个例子中,我们首先将 $identifier
转换为对应的十六进制表示形式,并加上前缀 x'
和后缀 '
来构造出正确的比较字符串。然后,我们将这个完整的字符串作为单个参数传递给查询,而不是尝试将其作为命名参数绑定。
这样,你可以保留对 $identifier
的动态处理,同时确保 SQL 查询的其余部分仍然是安全的。注意,这种方法假设 $identifier
已经是适合转换为十六进制表示的格式,如果 $identifier
是其他类型的数据,可能需要额外的处理步骤。