我想在sql server上创建函数来检查字符串值。
传递给两个参数:第一个原始'12.33.44.65.22'
,第二个'44.22'
并返回
true
中找到parameter2
,则 original parameter
例如:
call fun1('22.34.56.78' , '23.24') -- return false
call fun1('22.34.56.78' , '23.24') -- return false
call fun1('22.34.56.78.43.76' , '22.12') -- return false , because should be both exists
call fun1('22.34.56.78' , '22.56') -- return true
call fun1('21.34.56.54' , '21.56') -- return true
call fun1('21.34.56.54' , '34.56') -- return true
call fun1('22.34.56.78' , '34.55.35') -- return false
感谢。
答案 0 :(得分:1)
根据更新的问题,这不是答案。您希望确认分隔符值字符串中的所有值都存在于另一个分隔值的字符串中,在这种情况下,分隔符为“。”
select
case when charindex('44.22','12.33.44.65.22')>0 then 'true'
else 'false'
end
更新:如果搜索字符串始终采用该格式,则可以使用:
create function dbo.func1 (@StringToFind nvarchar(128), @StringToSearch nvarchar(128))
returns nvarchar(5) as
begin
return case
when charindex(left(@StringToFind,charindex('.',@StringToFind)-1),@StringToSearch)>0
and charindex(right(@StringToFind,charindex('.',reverse(@StringToFind))-1),@StringToSearch)>0
then 'true'
else 'false'
end;
end
go
select dbo.func1('44.22','12.33.44.65.22')
答案 1 :(得分:0)
Declare @YourTable table (TheString varchar(100), FindString varchar(100));
Insert Into @YourTable values
('22.34.56.78','23.24') -- return false
,('22.34.56.78.43.76','22.12') -- return false , because should be both exists
,('22.34.56.78','22.56') -- return true
,('21.34.56.54','21.56') -- return true
,('21.34.56.54','34.56') -- return true
,('22.34.56.78','34.55.35');
Select *
,InString = [dbo].[udf_InString](TheString,FindString)
From @YourTable
返回
TheString FindString InString
22.34.56.78 23.24 false
22.34.56.78.43.76 22.12 false
22.34.56.78 22.56 true
21.34.56.54 21.56 true
21.34.56.54 34.56 true
22.34.56.78 34.55.35 false
UDF
CREATE FUNCTION [dbo].[udf_InString](@String varchar(max),@Search varchar(max))
Returns varchar(25)
Begin
Declare @RetVal varchar(25)
;with cte as (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>'+ Replace(@String,'.','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
)
Select @RetVal = case when count(*)>0 then 'true' else 'false' end
From cte A
Join cte B on (A.RetSeq+1=B.RetSeq or A.RetSeq+2=B.RetSeq)
Where A.RetVal+'.'+B.RetVal = @Search
Return @RetVal
End
答案 2 :(得分:0)
您可以这样尝试:
我首先使用XML技巧将分隔的字符串拆分为它们的部分(获取派生表)。 INNER JOIN
将它们缩减为双方包含的部分。剩下的就是计算:如果公共元素的数量等于第2侧的总数,则所有元素都是常见的:
注意:任何没有共同元素的行都会被忽略。您可以对所有现有ID的LEFT JOIN
列表使用DISTINCT
来包含没有值交叉的行...
应该很容易从此创建一个功能。只需将两个字符串作为参数输入,并将TheString
和CheckString
替换为它们(并删除FROM @dummyTbl
)。在这种情况下,空结果为false
。
DECLARE @dummyTbl TABLE(ID INT IDENTITY,TheString VARCHAR(100), CheckString VARCHAR(100));
INSERT INTO @dummyTbl VALUES
('22.34.56.78','23.24') -- return false
,('22.34.56.78.43.76','22.12') -- return false , because should be both exists
,('22.34.56.78','22.56') -- return true
,('21.34.56.54','21.56') -- return true
,('21.34.56.54','34.56') -- return true
,('22.34.56.78','34.55.35');
WITH casted AS
(
SELECT ID
,CAST('<x>' + REPLACE(TheString,'.','</x><x>') + '</x>' AS XML) AS s1
,CAST('<x>' + REPLACE(CheckString,'.','</x><x>') + '</x>' AS XML) AS s2
FROM @dummyTbl
)
,s1Tbl AS
(
SELECT ID,x.value('.','int') Val
FROM casted
CROSS APPLY s1.nodes('/x') AS A(x)
)
,s2Tbl AS
(
SELECT ID,x.value('.','int') Val
FROM casted
CROSS APPLY s2.nodes('/x') AS A(x)
)
SELECT s1Tbl.ID
,CASE WHEN COUNT(s1Tbl.ID)=(SELECT COUNT(x.ID) FROM s2Tbl AS x WHERE x.ID=s1Tbl.ID) THEN 'true' else 'false' END AS FullyIncluded
FROM s1Tbl
INNER JOIN s2Tbl ON s1Tbl.Val=s2Tbl.Val AND s1Tbl.ID=s2Tbl.ID
GROUP BY s1Tbl.ID
答案 3 :(得分:0)
这是一个使用XML来吐出字符串的函数和一个反连接,以查看是否所有内容都匹配。然后你可以简单地将它称为交叉应用,如下所示。
CREATE FUNCTION dbo.FindStringsInString(
@String VARCHAR(MAX)
,@SearchString VARCHAR(MAX)
)
RETURNS BIt
AS
BEGIN
IF (COALESCE(LEN(@String),0) = 0 OR COALESCE(LEN(@SearchString),0) = 0)
BEGIN
--either the String or the SearchString is Null or Empty
RETURN 0
END
DECLARE @XMLString XML = CAST('<X>' + REPLACE(@String,'.','</X><X>') + '</X>' AS XML)
DECLARE @XMLSearchString XML = CAST('<X>' + REPLACE(@SearchString,'.','</X><X>') + '</X>' AS XML)
IF NOT EXISTS (
SELECT 1
FROM
(
SELECT
n.value('.', 'varchar(MAX)') as S
FROM
@XMLSearchString.nodes('X') as t(n)) searchstring
LEFT JOIN (
SELECT
n.value('.', 'varchar(MAX)') as S
FROM
@XMLString.nodes('X') as t(n)) string
ON searchstring.S = string.S
WHERE
string.S IS NULL
)
BEGIN
--All of the values in the Search StringMatch a Value in the String
RETURN 1
END
--default if it hasn't returned by now it is false
RETURN 0
END
GO
测试数据,我添加了NULL和&#39;&#39;案例和从功能中选择:
DECLARE @Table AS TABLE (String VARCHAR(100), SearchString VARCHAR(100))
INSERT INTO @Table VALUES
('22.34.56.78' , '23.24') -- return false
,('22.34.56.78' , '23.24') -- return false
,('22.34.56.78.43.76' , '22.12') -- return false , because should be both exists
,('22.34.56.78' , '22.56') -- return true
,('21.34.56.54' , '21.56') -- return true
,('21.34.56.54' , '34.56') -- return true
,('22.34.56.78' , '34.55.35') -- return false
,('22.34.56.78' , NULL) -- return false
,('22.34.56.78' , '') -- return false
,(NULL , '34.55.35') -- return false
,('' , '34.55.35') -- return false
SELECT *
FROM
@Table t
CROSS APPLY (SELECT
dbo.FindStringsInString(t.String, t.SearchString)) s(Match)