通过将字符串转换为 int 来防止 MySql 修改查询

Sha*_*ane 11 mysql

在我的一张表上,我有一个自动递增的 ID 字段。它还有另一个具有唯一约束的字段 (richter_code),但随着季节的变化,该字段可能会发生变化 - 这就是我不将其用作主键的原因。

在我的程序代码中,我有一个加载功能。它做的第一件事是检查richter_code 字段的搜索参数。如果它没有返回任何内容,它就会继续在 ID 字段上搜索相同的参数。

问题是它似乎在遇到字母字符时立即截断该值。所以我从我的查询中得到了完整的垃圾。例如,请参见屏幕截图。我可以阻止 mysql 更改查询吗?

截屏

Mat*_*don 10

一定要喜欢 MySql ;)

我在 Stack Overflow 上搜索了一个相当于某个isnumeric函数的 MySql ,并找到了这个

这个相当复杂的 WHERE 子句将返回预期的 0 行:

where Id = case when concat('','3R100C'*1) = '3R100C' then '3R100C' else null end
Run Code Online (Sandbox Code Playgroud)

这个想法是只在参数Id 是有效数值时才匹配参数。希望能帮助到你!


我会创建一个实际的isinteger函数来抽象出这种纯粹的疯狂:

CREATE FUNCTION `isinteger`(v varchar(255)) RETURNS bit(1)
BEGIN

    RETURN CASE WHEN CONCAT('', v * 1) = v THEN 1 ELSE 0 END;

END
Run Code Online (Sandbox Code Playgroud)

也就是说,我认为使用自动递增Id字段作为搜索回退列是不正确的——这个 ID 是你的表的主键,它的含义严格属于数据库端,任何程序都不应该关心它,更不用说程序的用户。

  • 我认为你可以使用 `else null` 而不是 `else -1` (2认同)
  • 我会担心调用自定义函数的性能(性能损失,如果有的话,我不知道)。两种解决方案的基准测试会很有趣。 (2认同)

小智 7

这里的问题是,在进行比较时,MySQL 正在进行从字符串到 int 的隐式转换......

SELECT * FROM cloths WHERE id = "3R100C"
Run Code Online (Sandbox Code Playgroud)

使转换显式,这就是 MySQL 正在做的事情:

SELECT * FROM cloths WHERE id = CAST("3R100C" as int)
Run Code Online (Sandbox Code Playgroud)

相反,您想要做的是将 id 转换为字符串,然后以这种方式进行比较。解决方法很简单:

SELECT * FROM cloths WHERE CAST (id as varchar(10)) = "3R100C"
Run Code Online (Sandbox Code Playgroud)

这将消除对字符串端的整数处理/解析的任何需要。