我有这个 Postgres 功能。它强制文本为小写,所有空值变为空字符串,以便我更干净地执行搜索不匹配的内容等:
CREATE OR REPLACE FUNCTION magic_text(txt text) RETURNS text
IMMUTABLE PARALLEL SAFE
LANGUAGE SQL AS $$
SELECT lower(coalesce(txt,''))
$$;
Run Code Online (Sandbox Code Playgroud)
这个函数在许多不同的查询类型中被大量使用,所以我为它创建了所有种类的文本索引:
CREATE INDEX index_magic_cards_on_oracle_text_magic
ON magic_cards
USING BTREE (magic_text(oracle_text)) WITH (fillfactor = 100);
CREATE INDEX index_magic_cards_on_oracle_text_magic_text_pattern
ON magic_cards
USING BTREE (magic_text(oracle_text) text_pattern_ops) WITH (fillfactor = 100);
CREATE INDEX index_magic_cards_on_oracle_text_magic_gist_trgm
ON magic_cards
USING GIST (magic_text(oracle_text) gist_trgm_ops);
CREATE INDEX index_magic_cards_on_oracle_text_magic_gin_trgm
ON magic_cards
USING GIN (magic_text(oracle_text) gin_trgm_ops)
Run Code Online (Sandbox Code Playgroud)
这些索引以某种方式干扰了某些(但不是全部)类型的复杂正则表达式搜索。我无法确定特定的正则表达式符号或功能是否会导致问题。
这是一个示例(explain.depesz):
SELECT card_name
FROM magic_cards
WHERE magic_text(oracle_text) ~ '***:(?n)eldrazi\ (?!scion)';
Run Code Online (Sandbox Code Playgroud)
这不返回任何内容,并且根据查询规划器,它会在 上执行位图索引扫描 …
我将正则表达式作为varchar
s存储在列中,我需要将其与传入的输入进行匹配。例如,该表可能包含:
| field | value |
|-------|---------------|
| email | .*@domain.com |
Run Code Online (Sandbox Code Playgroud)
查询将是:
SELECT *
FROM table
WHERE field = 'email'
AND 'someone@domain.com' ~* value
Run Code Online (Sandbox Code Playgroud)
我将是第一个承认这很愚蠢的人,尽管它在大约 2 年中做得足够好。该表现在达到了令人震惊的 10k 行,查询速度减慢到 3 秒的数量级。我已经把我们带到了一个更合理的策略,所以这个问题纯粹是学术性的。
如果我保留了这个设置,有什么办法可以提高查找效率吗?我希望有 的一些兄弟姐妹varchar_pattern_ops
,但这个查询与解决的问题相反。
有了这个想法,这里是完整的表格、查询和解释。
+------------+-----------------------------+------------------------------------------------------------+
| Column | Type | Modifiers |
|------------+-----------------------------+------------------------------------------------------------|
| id | integer | not null default nextval('table_id_seq'::regclass) |
| field | character varying(255) | not null |
| value | character varying(1000) | not null |
| comment | text …
Run Code Online (Sandbox Code Playgroud) 例如,如果我运行以下查询,WHERE 子句中的表达式将只匹配数字前的第一个字母,但有没有办法先匹配一个或多个字母(例如,在字母数量可变的情况下)在我过滤的字段中的数字之前)?
SELECT FilteredField
FROM Table
WHERE FilteredField LIKE '[a-zA-Z][0-9]'
Run Code Online (Sandbox Code Playgroud)
示例数据:
本质上,当使用 LIKE 运算符时,我正在寻找与 RegEx +等效的 SQL Server 2016 。
我有下表,我试图将列“前缀”限制为 ASCII 字母字符。但是,在使用以下约束后,我仍然可以插入其他字符。为什么它不起作用?
CREATE TABLE test
(
id INTEGER NOT NULL PRIMARY KEY,
prefix TEXT NOT NULL,
CHECK(prefix NOT LIKE '%[^a-zA-Z]%')
)
Run Code Online (Sandbox Code Playgroud)
使用 Python 的 sqlite3 包和 DB Browser for SQLite
主要问题我们需要在MS SQL Server 2019上使用正则表达式,能力至少达到POSIX正则表达式的水平。
这个来自 stackoverflow 的问答正确地得出结论,如果您的查询必须依赖正则表达式,您应该使用 CLR。这篇 Readgate文章详细阐述了这种方法。所以我和我的一位同事提出了这个解决方案,但我的另一位同事断然表示,在这里使用 CLR 会给安全性和稳定性带来巨大风险,而使用外部脚本(Python 或 R)更安全。
这似乎是一个可疑的说法,因为CLR 中的用户代码是可以管理的,所以也许正好相反,但我没能说服我的同事。
在我绝望中写的另一个问题中,因为我被迫使用外部脚本并且仍然产生一个极快的查询。SQLpro 用户在他的评论中指出:
就安全性而言,使用 Python 或 R 可能比使用 CLR 更糟糕!
我倾向于相信。
所以我有两个问题:
sql-server regular-expression sql-clr python external-scripts
我试图456
从字符串中提取:123:456:
如下:
select regexp_substr(':123:456:', ':(\d+):', 1, 2, 'i', 1) from dual
Run Code Online (Sandbox Code Playgroud)
但是,此查询返回null
。我究竟做错了什么?
我正在为跟踪有关我公司的数据库开发项目的信息的应用程序设计数据库。项目管理办公室 (PMO) 根据项目的成本是否计入合并整合,为每个项目分配一个伪编号。举例来说,分配的数字将以INT(对于有助于合并整合的项目)或NINT(对于不有助于合并整合的项目)开头。然后分配一个序列号。例如,INT175将是第 175 个确定有助于合并整合的项目。另一个问题是 PMO 有时希望创建多个具有相同编号的项目,因为它们是“相关的”。因此,例如可能有一个 INT175 a项目、INT175 b项目等。
虽然 PMO 认为这个数字是项目的标识符,但在数据库中,我只会将该列用作备用唯一键,以确保不会创建重复的项目并作为用户的搜索键。我想对该列实施检查约束,以确保只能输入与我上面给出的规则匹配的有效数字。
我的第一个想法是使用正则表达式。在 Oracle 中,我的目标 DBMS,我们有可以使用的 REGEX_LIKE 函数。我研究了关于正则表达式的文档(这里、这里、这里、这里和这里),发现这些选项令人眼花缭乱!无论出于何种原因,我的大脑都在试图获取所有各种模式匹配选项的列表并将其应用到我的特定示例中。我是最擅长使用示例的人之一。不幸的是,我还没有找到很多例子。我发现的东西要么太简单,要么太复杂,我无法理解它们。
到目前为止我尝试过的是这样的:
select c
from (
select 'INT1756b' c from dual union all
select 'INT175a' c from dual union all
select 'INT75a' c from dual union all
select 'INT75' c from dual union all
select 'NINT2283a' c from dual union …
Run Code Online (Sandbox Code Playgroud) 我有一个表,其中每一行都有如下数据:
0150566115,"HEALTH 401K","IC,ON","ICON HEALTH 401K",,,1,08/21/2014
Run Code Online (Sandbox Code Playgroud)
我想要的是删除,
包含在双引号“”之间的每个逗号 ( )。然后用逗号 ( ,
)分割字符串的其余部分
我不想检查双引号开始和结束的每个字符设置标志。
我可以实现某种正则表达式吗?
有没有简单的方法?
到目前为止,我所尝试的只是根据逗号 ( ,
)拆分字符串,但它也在拆分引号内的值。
这是为了达到目的:如何在完整的表中实现这一点(目前,如果我只有一个双引号块实例,它就可以工作)?
Declare @Query nvarchar(max)
Set @Query = 'Item1,Item2,"Item,Demo,3",New'
Declare @start int, @len int
SELECT @start = PATINDEX('%"%"%', @Query) + 1
print @start
select @len = CHARINDEX('"', SUBSTRING(@Query, @start, LEN(@Query))) - 1
select
SUBSTRING(@Query, 1, @start - 2) +
REPLACE((SUBSTRING(@Query, @start, @len)), ',', '') +
SUBSTRING(@Query, @start + @len + 1, LEN(@Query))
Run Code Online (Sandbox Code Playgroud)
这是我用来分割的函数
ALTER FUNCTION [dbo].[fnSplit](
@sInputList VARCHAR(8000) -- List of …
Run Code Online (Sandbox Code Playgroud) regex ×3
sql-server ×3
index ×2
postgresql ×2
t-sql ×2
constraint ×1
functions ×1
oracle ×1
oracle-11g ×1
python ×1
sql-clr ×1
sqlite ×1