【问题标题】:SQL Server studio Function variable scope errorSQL Server studio 函数变量范围错误
【发布时间】: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”

任何帮助都是有价值的,并且会带来新的学习!

【问题讨论】:

标签: sql sql-server tsql stored-procedures stored-functions


【解决方案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 不变。

    这是结果的截屏视频。

    谢谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多