You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLite3中CHECK约束内LIKE语句失效,手机号正则验证失败求助

问题分析与解决方案

核心问题原因

你的问题出在SQLite对LIKE和正则的支持逻辑上:

  1. SQLite的LIKE操作符不支持正则表达式语法(如^、$、{10}这类锚点和重复次数标记),它仅识别%(任意长度字符)、_(单个字符)作为通配符,默认也不支持[0-9]这类字符集匹配。
  2. Python的sqlite3模块默认未内置REGEXP函数,直接使用会报错;而SQL控制台可能已预装了相关扩展,所以能正常运行。
  3. 你尝试的[0-9]重复写法无效,也是因为SQLite默认LIKE不支持字符集语法。

可行解决方案

方案1:用SQLite内置函数验证全数字(最简方案)

利用CAST()函数特性:如果字符串包含非数字字符,CAST(phone_number AS INTEGER)会返回NULL,结合已有的长度约束即可实现验证。

修改后的Customers表创建语句:

create table if not exists Customers(
    phone_number nvarchar(10) primary key,
    first_name nvarchar(15),
    last_name nvarchar(15),
    city nvarchar(20),
    address nvarchar(50),
    backup_phone nvarchar(10),
    password nvarchar(20),
    check (length(phone_number) = 10),
    check (phone_number != backup_phone),
    check (CAST(phone_number AS INTEGER) IS NOT NULL),
    check (length(password) >= 8 and length(password) <= 20)
 )

另外注意:SQLite中auto_increment必须搭配integer primary key使用,你的Products表中id_number int auto_increment写法有误,应改为id_number integer primary key autoincrement。

方案2:注册自定义REGEXP函数(最灵活方案)

在Python中通过create_function注册正则匹配函数,这样就能在CHECK约束中使用标准正则语法:

import sqlite3
import re

def regexp(expr, item):
    reg = re.compile(expr)
    return reg.search(item) is not None

def create_table():
    customers_table = """
    create table if not exists Customers(
        phone_number nvarchar(10) primary key,
        first_name nvarchar(15),
        last_name nvarchar(15),
        city nvarchar(20),
        address nvarchar(50),
        backup_phone nvarchar(10),
        password nvarchar(20),
        check (phone_number REGEXP '^[0-9]{10}$'),
        check (phone_number != backup_phone),
        check (password REGEXP '^.{8,20}$')
     )
    """
    
    products_table = """
    create table if not exists Products(
        id_number integer primary key autoincrement,
        name nvarchar(50),
        img_path nvarchar(100),
        price nvarchar(10),
        description nvarchar(200),
        publish_year nvarchar(20),
        author_name nvarchar(20)
    )
    """
    
    with sqlite3.connect("Shopping.db") as connection:
        # 注册REGEXP函数
        connection.create_function("REGEXP", 2, regexp)
        cursor = connection.cursor()
        try:
            cursor.execute(customers_table)
            cursor.execute(products_table)
            connection.commit()
        except Exception as e:
            print(e)
            connection.rollback()

方案3:用SQLite的GLOB操作符

GLOB支持[0-9]这类字符集匹配,语法类似简化版正则:

check (phone_number GLOB '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')

或结合长度约束简化:

check (length(phone_number) = 10),
check (phone_number GLOB '^[0-9]*$')

内容的提问来源于stack exchange,提问作者Mohammad Ghanayem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:05:07