【问题标题】:Using GLOB to match each character in an SQLite TEXT field使用 GLOB 匹配 SQLite TEXT 字段中的每个字符
【发布时间】:2020-10-04 03:51:10
【问题描述】:

我在 SQLite 表中有一个 TEXT 字段,该字段的长度必须正好为 17 个字符。我们就叫它myfield吧。

对于此表中的任意行,我们如何在CHECK 括号内使用SQLite 的GLOB 运算符来匹配myfield 列条目中的每个字符(并且,如果可能,强制执行17 个字符的约束)?

此条目中的每个字符都可以是任何数字 0 - 9,或除 IOQ 之外的任何大写字母。还有,myfield条目的第9个字符只能是数字0 - 9或者字母X,不过我还是想先得到之前的条件。

我尝试了什么?

  1. CHECK(myfield GLOB '[A-HJ-NPR-Z0-9]{17}') - 这不起作用,我认为这是因为 GLOB 不支持大括号符号 - 如果我错了,请纠正我。
  2. CHECK(length(myfield) == 17 AND myfield GLOB '[A-HJ-NPR-Z0-9]') - 也不起作用,大概是因为第二个检查条件只匹配一个字符,与第一个相矛盾。
  3. 我相信有一个比为字符串中的每个字符设置 17 个检查条件更简单的解决方案!

【问题讨论】:

  • 如果您可以添加REGEXP用户定义函数(see here),那么您可以使用:CHECK(myfield REGEXP '^[A-HJ-NPR-Z0-9]{17}$')
  • @TimBiegeleisen 那太好了——我有一个使用REGEXP 的有效解决方案——但我要解决的问题的范围要求我坚持使用GLOB。跨度>
  • 你可以看看字符串函数 trim() 看看你能不能用它做点什么。

标签: sqlite glob


【解决方案1】:

在 SQLite 中,有一个 trick 来模拟像 MySql 的 REPEAT() 这样的函数,它返回一个重复 n 次的字符串。
所以通过:

REPLACE(HEX(ZEROBLOB(8)), '00', '[A-HJ-NPR-Z0-9]')

你得到字符串'[A-HJ-NPR-Z0-9]'重复8次:

[A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9]

您可以使用此技巧在CHECK 约束中的GLOB 之后(通过连接)构造您需要的字符串:

CHECK(myfield GLOB 
                REPLACE(HEX(ZEROBLOB(8)), '00', '[A-HJ-NPR-Z0-9]') || 
                '[X0-9]' || 
                REPLACE(HEX(ZEROBLOB(8)), '00', '[A-HJ-NPR-Z0-9]')
)

查看简化的demo

【讨论】:

    【解决方案2】:

    简单复制粘贴17次

    检查(myfield GLOB“[A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0- 9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][X0-9 ][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ- NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9]")

    在第 9 个元素处,只需键入 X0-9,因此“myfield 条目的第 9 个字符只能是数字 0 - 9 或字母 X”也可以检查 通过这样做,您还可以强制执行 17 个字符的限制

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-06
      • 1970-01-01
      • 1970-01-01
      • 2020-11-16
      • 1970-01-01
      • 2021-11-22
      • 1970-01-01
      相关资源
      最近更新 更多