SQL Server studio 函数变量范围错误
Posted
技术标签:
【中文标题】SQL Server studio 函数变量范围错误【英文标题】:SQL Server studio Function variable scope error 【发布时间】:2018-08-14 11:58:56 【问题描述】:我试图使用一个函数作为练习,其中我有 2 个由 ;
分隔的字符串(例如:'1;22;333;444;;5555;666')和另一个格式相同的字符串。
我想检查在大数据集的情况下,两个字符串中是否有相同的元素
例子
@string1 : 'a','b','c'
@string2 : 'a','g','c'
在这种情况下,我希望答案为假,因为 B 和 C 不在第二个字符串中。
示例 2
@string1 : 'a','b','c'
@string2 : 'a','b','c'
在这种情况下,答案将是正确的。
到目前为止,我正在做这样的事情:
CREATE FUNCTION dbo.fnSplit(
@sInputList VARCHAR(8000), -- List of delimited items
@sDelimiter VARCHAR(8000) = ',' -- delimiter that separates items
)
RETURNS @List TABLE (item VARCHAR(8000))
BEGIN
DECLARE @sItem VARCHAR(8000)
WHILE CHARINDEX(@sDelimiter, @sInputList, 0) <> 0
BEGIN
SELECT
@sItem = RTRIM(LTRIM(SUBSTRING(@sInputList, 1, CHARINDEX(@sDelimiter, @sInputList, 0) - 1))),
@sInputList = RTRIM(LTRIM(SUBSTRING(@sInputList, CHARINDEX(@sDelimiter, @sInputList, 0) + LEN(@sDelimiter), LEN(@sInputList))))
IF LEN(@sItem) > 0
INSERT INTO @List
SELECT @sItem
END
IF LEN(@sInputList) > 0
INSERT INTO @List
SELECT @sInputList -- Put the last item in
RETURN
END
GO
select * from dbo.fnSplit('1;22;333;444;;5555;666', ';')
导致
1
22
333
444
5555
666
然后我有另一个导致错误的函数:
CREATE FUNCTION dbo.fnSplitFinal(
@sInputList VARCHAR(8000) -- List of delimited items (source string)
, @sInputList2 VARCHAR(8000) -- List of delimited items2(target string)
, @sDelimiter VARCHAR(8000) = ',' -- delimiter that separates items source
, @sDelimiter2 VARCHAR(8000) = ',' -- delimiter that separates items target
) RETURNS Integer
BEGIN
DECLARE @list1 TABLE (item VARCHAR(8000));
DECLARE @list2 TABLE (item VARCHAR(8000));
DECLARE @listFinal TABLE (item VARCHAR(8000), item2 Varchar(8000), Istrue varchar(50)) ;
--source
Insert Into @list1 (Item)
select * from master.dbo.fnSplit(@sInputList, ';')
--target
Insert Into @list2 (Item)
select * from Master.dbo.fnSplit(@sInputList2,';')
--final
insert Into @listFinal (Item, item2, istrue)
select a.item , b.item,
Case
when a.item = b.item then 'true'
when a.item != b.item then 'false'
when a.item is not NULL and b.item is NULL then 'falseNULL'
else 'cc'
end as Istrue
from @list1 --> error here, out of scope?
left Join @list2
on @list1.item = List2.item
Declare @result Integer
select @result = (select count(*) from @listFinal where isTrue !="true" )
RETURN @result
END
GO
这显示错误“必须声明一个标量变量@list1”
任何帮助都是有价值的,并且会带来新的学习!
【问题讨论】:
错误查询中的 a 和 b 别名是什么? 我强烈建议您将当前的拆分功能扔进垃圾桶。有许多选项比使用 while 循环更适合拆分字符串。这里有几个。 sqlperformance.com/2012/07/t-sql-queries/split-strings 【参考方案1】:这对我有用:
ALTER FUNCTION dbo.fnSplitFinal(
@sInputList VARCHAR(8000) -- List of delimited items (source string)
, @sInputList2 VARCHAR(8000) -- List of delimited items2(target string)
, @sDelimiter VARCHAR(8000) = ',' -- delimiter that separates items source
, @sDelimiter2 VARCHAR(8000) = ',' -- delimiter that separates items target
) RETURNS Integer
BEGIN
DECLARE @list1 TABLE (item VARCHAR(8000));
DECLARE @list2 TABLE (item VARCHAR(8000));
DECLARE @result INT
--source
Insert Into @list1 (Item)
select * from dbo.fnSplit(@sInputList, @sDelimiter)
--target
Insert Into @list2 (Item)
select * from dbo.fnSplit(@sInputList2,@sDelimiter2)
--final
SELECT @result = COUNT(*)
FROM @list1
WHERE item NOT IN
(
SELECT item FROM @list2
);
RETURN @result
END
GO
我将您的@delimiter 参数放入函数中,为@result 变量添加了声明,并简化了最终查询。
【讨论】:
【参考方案2】:感谢大家的支持。我终于想通了这一点。这是我对问题的解决方案。
ALTER FUNCTION dbo.fnSplitFinal(
@sInputList VARCHAR(8000) -- List of delimited items (source string)
, @sInputList2 VARCHAR(8000) -- List of delimited items2(target string)
, @sDelimiter VARCHAR(8000) = ',' -- delimiter that separates items source
, @sDelimiter2 VARCHAR(8000) = ',' -- delimiter that separates items target
) RETURNS @FinalResult TABLE (isTrue VARCHAR(8000), Missing varchar(2000))
BEGIN
DECLARE @list1 TABLE (item VARCHAR(8000));
DECLARE @list2 TABLE (item VARCHAR(8000));
DECLARE @listFinal TABLE (item VARCHAR(8000), item2 Varchar(8000), Istrue varchar(50)) ;
--source
Insert Into @list1 (Item)
select * from master.dbo.fnSplit(@sInputList, ';')
--target
Insert Into @list2 (Item)
select * from Master.dbo.fnSplit(@sInputList2,';')
--final
insert Into @listFinal (Item, item2, istrue)
select a.item , b.item,
Case
when ltrim(rtrim(a.item)) = ltrim(rtrim(b.item)) then 'true' -- Matching Value found
when ltrim(rtrim(a.item)) !=ltrim(rtrim(b.item)) then 'false' -- There is a mismatch in the value // not able to join also.
when a.item is not NULL and b.item is NULL then a.item+' is missing in the target'
When b.item is NOT NULL and A.item is NULL then b.item+' in target, not in source'
else 'CheckAgain'
end as Istrue
from @list1 a
left Join @list2 b
on a.item = b.item
DECLARE @error VARCHAR(8000)
SELECT @error = COALESCE(@error + ', ', '') + istrue
FROM @listFinal where istrue !='True'
Declare @result Integer
select @result = (select count(*) from @listFinal where Istrue != 'True')
IF @result > 0
INSERT INTO @FinalResult(isTrue,Missing) SELECT 'false',@error --isTrue from @listFinal where Istrue!='true'
IF @result = 0
INSERT INTO @FinalResult(isTrue,Missing) SELECT 'True','NULL'
RETURN
END
GO
保持 fnsplit 不变。
这是结果的截屏视频。
谢谢!
【讨论】:
以上是关于SQL Server studio 函数变量范围错误的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server 及 Visual Studio的离线帮助文档
sql server中单引号拼接字符串(书写错误会出现错误"浮点值 XXXX 超出了计算机表示范围(8 个字节)。“XX”附近有语法错误。")