Reputation: 2184
I'm using SQL Server 2014. I have a table function which takes 2 parameters and returns 2 columns. For the sake of simplicity, let's call the function Get_GroupNumber.
Get_GroupNumber('Smith', '123-456-789')
This will return 2 columns. Again keeping it simple let's say it is Reason1 and Reason2.
Reason1 = '111-222-333'
Reason2 = '555'666'777'
I need to pass Reason1 which is returned back into Get_GroupNumber
, and keep doing so until it returns a NULL in Reason1 and also NULL in Reason2.
So, the second call would look like this:
Get_GroupNumber('Smith','111-222-333')
Upvotes: 3
Views: 117
Reputation: 2184
Using While Loop
DECLARE @key varchar(max);
DECLARE @retVal varchar(max);
SET @key = '123-456-789'
While @Key is not null
BEGIN
set @retval = @key
SET @key = (SELECT Return2 from [dbo].[Get_GroupNumber]('Smith',@key))
END;
print @retVal
I know I'm only using the return value from column Return2 to test here
Upvotes: 0
Reputation: 3542
If you don't want to use an iterative approach (e.g., with a while
loop), then a recursive CTE can do the job. You can read more about recursive CTEs here, or check out this example:
-- Here's a "dummy" function that has some hard-coded return values for illustrative
-- purposes. It will return ('111-222-333', '555-666-777') when it gets 123-456-789
-- as its second parameter, ('999-999-999', '000-000-000') when it gets 111-222-333
-- as its second parameter, and (null, null) otherwise.
create function Get_GroupNumber
(
@Param1 varchar(32),
@Param2 varchar(32)
)
returns table
as
return
(
select
Reason1 = case @Param2 when '123-456-789' then '111-222-333' when '111-222-333' then '999-999-999' else null end,
Reason2 = case @Param2 when '123-456-789' then '555-666-777' when '111-222-333' then '000-000-000' else null end
);
go
-- The sample inputs from your question.
declare @Param1 varchar(32) = 'Smith';
declare @Param2 varchar(32) = '123-456-789';
-- And finally, the good stuff:
with GroupNumberCTE as
(
-- Base case: pass the original parameters, get the results from the function, and
-- create a new field called "Call #" that will illustrate the order in which the
-- various calls to Get_GroupNumber were made. (This field is purely informational;
-- you can remove it if you don't want it.)
select
[Call #] = 1,
Reason1,
Reason2
from
Get_GroupNumber(@Param1, @Param2)
union all
-- Recursive case: if the previous call returned a non-null value in either field,
-- invoke the function again with the original @Param1 and the Reason1 from the
-- previous call.
select
[Call #] = [Previous].[Call #] + 1,
[Next].Reason1,
[Next].Reason2
from
GroupNumberCTE [Previous]
cross apply Get_GroupNumber(@Param1, [Previous].Reason1) [Next]
where
[Previous].Reason1 is not null or
[Previous].Reason2 is not null
)
select * from GroupNumberCTE;
The result set:
Call # Reason1 Reason2
----------------------------------
1 111-222-333 555-666-777
2 999-999-999 000-000-000
3 NULL NULL
I should point out that there's a danger here: there is nothing in the structure of my CTE itself that guarantees that the recursion will eventually end. So you'll have to be sure that for any feasible set of initial inputs, your implementation of Get_GroupNumber
will eventually return two nulls. As long as that is so, this approach should work well.
Upvotes: 4