Reputation: 1710
Didn't manage to find an aswer for the problem. Therefore, decided to share it here. Hope it will help anybody and professionals will share more efficient solution
I created a function in MSSQL that takes a parameter and try to find corresponding record in a mapping table. The extraction of mapping record was implemented using 'With clause':
CREATE FUNCTION [dbo].[GetMappedValue]
(
@field nvarchar(50) = null
)
RETURNS VARCHAR(50)
AS
BEGIN
;WITH active_mappings AS
(SELECT map_key, map_value, ROW_NUMBER() OVER (PARTITION BY map_key ORDER BY updated DESC) AS n
FROM MappingTable WHERE tag = 'Active')
RETURN SELECT TOP 1 map_value FROM active_mappings
WHERE n=1 AND map_key = @field
END
GO
But for a strange reason: 'RETURN statements in scalar valued functions must include an argument' error occurs
Upvotes: 1
Views: 5927
Reputation: 33581
Here is how this same function would look as an inline table valued function.
CREATE FUNCTION [dbo].[GetMappedValue]
(
@field nvarchar(50) = null
)
RETURNS TABLE AS RETURN
WITH active_mappings AS
(
SELECT map_value
, ROW_NUMBER() OVER (PARTITION BY map_key ORDER BY updated DESC) AS n
FROM MappingTable
WHERE tag = 'Active'
AND map_key = @field
)
SELECT TOP 1 map_value
FROM active_mappings
WHERE n = 1
--ORDER BY ??? You have top 1 but no order by. As such you don't know which row will be returned
GO
---EDIT---
Since you said there can only be a single value returned from MappingTable you could greatly simplify this. The entire body of your function could be this simple.
select map_value
from MappingTable mt
where tag = 'Active'
and map_key = @field
Upvotes: 1
Reputation: 1710
In order to solve the problem I had to declare a variable and assign result of select into the variable and only afterwards return it:
CREATE FUNCTION [dbo].[GetMappedValue]
(
@field nvarchar(50) = null
)
RETURNS VARCHAR(50)
AS
BEGIN
Declare @result nvarchar(50)
;WITH active_mappings AS
(SELECT map_key, map_value, ROW_NUMBER() OVER (PARTITION BY map_key ORDER BY updated DESC) AS n
FROM MappingTable WHERE tag = 'Active')
SELECT @Result = (SELECT TOP 1 map_value FROM active_mappings
WHERE n=1 AND map_key = @field)
RETURN @Result
END
GO
Upvotes: 4