开发者社区 问答 正文

Laravel模型,选择带有十六进制的查询

我在使用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一起正确注入,使其像手动操作一样工作?

展开
收起
社区秘书 2019-12-04 13:56:21 641 分享 版权
阿里云 AI 助理回答

在 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 是其他类型的数据,可能需要额外的处理步骤。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答地址: