Tsql T-SQL:在字符串中查找列匹配项(类似但不同)
服务器:SQL Server 2008 R2 我提前道歉,因为我不确定用什么方式来表达这个问题。我正在接收一个电子邮件地址字符串,我需要查看该字符串中是否有任何地址已经作为用户存在。下面显示了显然不起作用的查询,但希望它有助于澄清我在寻找什么: 我希望SQL有一个“InString”操作符,可以检查“字符串内”的匹配,但我认为我的Google能力今天一定很弱 非常感谢您的帮助。如果真的没有办法,我将不得不深入研究并在codebehind中做一些工作,以分割字符串中的每个项目并搜索每个项目 提前感谢,,Tsql T-SQL:在字符串中查找列匹配项(类似但不同),tsql,sql-server-2008-r2,Tsql,Sql Server 2008 R2,服务器:SQL Server 2008 R2 我提前道歉,因为我不确定用什么方式来表达这个问题。我正在接收一个电子邮件地址字符串,我需要查看该字符串中是否有任何地址已经作为用户存在。下面显示了显然不起作用的查询,但希望它有助于澄清我在寻找什么: 我希望SQL有一个“InString”操作符,可以检查“字符串内”的匹配,但我认为我的Google能力今天一定很弱 非常感谢您的帮助。如果真的没有办法,我将不得不深入研究并在codebehind中做一些工作,以分割字符串中的每个项目并搜索每个项目 提前
BeemsSQL有一个
包含和IN
函数。您可以使用其中任何一个来完成任务。通过MSDNs网站点击其中一个以获取更多信息!希望这有帮助
CONTAINS
将查看数据中的任何值是否包含您提供的整个字符串。在演示文稿中类似于,如“%myValue%”代码>
SELECT f_emailaddress
FROM tb_users
WHERE CONTAINS (f_emailaddress, 'user1@domain.com');
中的将为提供的逗号分隔列表中的任何值返回匹配项。然而,它们需要精确匹配。您不能提供部分条款
SELECT f_emailaddress
FROM tb_users
WHERE f_emailaddress IN ('user1@domain.com','user2@domain.com')
至于将每个值拆分为单独的字符串,请查看找到的StackOverflow问题。这可能会为您指明正确的方向。您可以这样尝试(未经测试)
在使用此方法之前,请确保已在该表和列上创建了全文索引
将逗号替换为,然后
SELECT id,email
FROM t
where CONTAINS(email, 'user1@domain.com and user2@domain.com');
您首先需要将CSV列表拆分为一个临时表,然后使用该临时表与现有表进行内部联接,因为这将充当一个过滤器
除非在该表和列上创建了全文索引,否则无法使用,我怀疑这里的情况是否如此
例如:
CREATE TABLE #EmailAddresses (Email NVARCHAR(500) NOT NULL);
INSERT INTO #EmailAddress (Email)
SELECT split.Val
FROM dbo.Splitter(@IncomingListOfEmailAddresses);
SELECT usr.f_emailaddress
FROM tb_users usr
INNER JOIN #EmailAddresses tmp
ON tmp.Email = usr.f_emailaddress;
请注意,对“dbo.Splitter”的引用是您已经拥有或可能获得的任何字符串拆分器的占位符。请不要使用任何使用WHILE
循环的拆分器。最好的选择是基于SQLCLR或XML的。基于XML的字符串通常很快,但如果要拆分的字符串具有特殊的XML字符,例如&
,拆分输入字符串并在子句中使用,则在编码方面确实存在一些问题
要将CSV拆分为行,请使用此选项
SELECT Ltrim(Rtrim(( Split.a.value('.', 'VARCHAR(100)') )))
FROM (SELECT Cast ('<M>'
+ Replace('user1@domain.com,user2@domain.com', ',', '</M><M>')
+ '</M>' AS XML) AS Data) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
谢谢你的回复。看起来这两种方法都会迫使我将字符串从接收格式中分离出来。不幸的是,我收到的信息如下所示:user1@domain.com,user2@domain.com“若要在中执行包含或,我似乎需要将其拆分。我能做到,我只是希望有一个更简单的解决办法。我想没什么大不了的,我会修改。@Beems好的,看看这篇文章,例如,CONTAINS查询给了我一个错误:从tb_用户中选择f_emailaddress,其中CONTAINS(f_emailaddress,'user1@domain.com,user2@domain.com'); 错误:“全文搜索条件中”“附近的语法错误”@Beems and Volearix:CONTAINS
仅适用于全文索引列。字符串拆分是一个非常常见的函数。如果您需要帮助,我建议您针对您使用的代码隐藏环境发布一个问题。阅读以下文章以了解答案-,-但是请注意,您想要避免的(在代码隐藏中执行)实际上是最好的解决方案。@srutzky感谢您告诉我。我知道。@Piyush如果你知道这一点,并且它与答案相关,那么在你的答案中包含它可能是一个好主意。由于您将此作为问题的解决方案,提出问题的人很可能不知道这一点,人们很少批评答案包含太多细节@srutzky和GarethD:-在回答中补充道,我还不确定这是如何工作的,但确实如此,所以谢谢。真诚地,谢谢你。我将把它剥开,读一些书,这样我就能理解它。@Beems这个链接可能会对你有所帮助
SELECT Ltrim(Rtrim(( Split.a.value('.', 'VARCHAR(100)') )))
FROM (SELECT Cast ('<M>'
+ Replace('user1@domain.com,user2@domain.com', ',', '</M><M>')
+ '</M>' AS XML) AS Data) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
SELECT f_emailaddress
FROM tb_users
WHERE f_emailaddress IN(SELECT Ltrim(Rtrim(( Split.a.value('.', 'VARCHAR(100)') )))
FROM (SELECT Cast ('<M>'
+ Replace('user1@domain.com,user2@domain.com', ',', '</M><M>')
+ '</M>' AS XML) AS Data) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a))
SELECT f_emailaddress
FROM tb_users A
JOIN (SELECT Ltrim(Rtrim(( Split.a.value('.', 'VARCHAR(100)') )))
FROM (SELECT Cast ('<M>'
+ Replace('user1@domain.com,user2@domain.com', ',', '</M><M>')
+ '</M>' AS XML) AS Data) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)) B
ON a.f_emailaddress = b.f_emailaddress
--prepare temp table for testing
DECLARE @tb_users AS TABLE
(f_emailaddress VARCHAR(100))
INSERT INTO @tb_users
( f_emailaddress)
VALUES ( 'user1@domain.com' ),
( 'user2@domain.com' ),
( 'user3@domain.com' ),
( 'user4@domain.com' )
--Your query
SELECT f_emailaddress
FROM @tb_users
WHERE 'user1@domain.com,user2@domain.com' LIKE '%' + f_emailaddress + '%'