【发布时间】:2021-10-08 15:10:53
【问题描述】:
我在表中有一个 nvarchar 列,将数据存储为“{CRLF}”分隔值。这些值可以是“namespace#name$value”格式,也可以是其他格式。
我需要提取分离的命名空间、名称和值,并跳过其他格式的数据。我可以通过查询来做到这一点:
select
SUBSTRING([value], 1, CHARINDEX('#',[value]) - 1) as paramNamespace,
SUBSTRING([value], CHARINDEX('#',[value]) + 1, CHARINDEX('$',[value]) - CHARINDEX('#',[value]) - 1) as paramName,
SUBSTRING([value], CHARINDEX('$',[value]) + 1, LEN([value])) as paramValue
FROM STRING_SPLIT(REPLACE((select data from test where Id = 1), '{CRLF}', CHAR(7)), CHAR(7))
WHERE [value] LIKE '%#%$%'
但是,当我尝试使用此查询按 paramName 过滤时:
select * from (select
SUBSTRING([value], 1, CHARINDEX('#',[value]) - 1) as paramNamespace,
SUBSTRING([value], CHARINDEX('#',[value]) + 1, CHARINDEX('$',[value]) - CHARINDEX('#',[value]) - 1) as paramName,
SUBSTRING([value], CHARINDEX('$',[value]) + 1, LEN([value])) as paramValue
FROM STRING_SPLIT(REPLACE((select data from test where Id = 1), '{CRLF}', CHAR(7)), CHAR(7))
WHERE [value] LIKE '%#%$%') a
where paramName IN ('name', 'name3')
返回
传递给 LEFT 或 SUBSTRING 函数的长度参数无效。
看起来 "WHERE [value] LIKE '%#%$%'" 没有首先执行,它尝试以其他格式对值进行子串化。
我应该如何编写这个查询来按 paramName 过滤它?
架构:
CREATE TABLE test (Id INT, data nvarchar(max));
INSERT INTO test VALUES (1, N'namespace#name$value{CRLF}somedatainotherformat{CRLF}namespace2#name2$value2{CRLF}namespace3#name3$value3{CRLF}');
【问题讨论】:
-
“我在表中有一个 nvarchar 列,将数据存储为 '{CRLF}' 分隔值” 这是 真正的 问题。修复您的设计,您就不会遇到此问题。永远不要在数据库中存储分隔数据。
-
这就是我使用此查询的目的,它是存储过程的一部分,它从分隔数据中提取值并将其存储在正确的列中。
-
那么,从您的样本数据来看,您在这里的预期结果是什么?
-
在我的简单数据中,有 3 个格式正确的值,因此它们被分成 3 行,参数名称为“name”、“name2”和“name3”。我想过滤它,所以它只返回 2 行带有 'name' 和 'name3',但是当我添加 'where paramName IN ('name', 'name3')' 它返回错误。
-
case when charindex('#',value)
标签: sql sql-server tsql sql-server-2017