Search code examples
sqlsql-servert-sqludftable-variable

Declare table variable in a UDF to enter table name as a parameter


I am working on a query and created a function to fetch result from outcomes table susing the following code.

CREATE FUNCTION dbo.Shippad (@tbl NVARCHAR(30))
RETURNS TABLE
AS
    RETURN
      SELECT LEFT(ship, Charindex(' ', ship) - 1) + ' '
             + Replicate('*', Charindex(' ', Substring(ship, Charindex(' ', ship) + 1, Len(ship))) + 1 -2)
             + ' '
             + Reverse(LEFT(Reverse(ship), Charindex(' ', Reverse(ship)) - 1)) as final_work 
      FROM   outcomes
      WHERE  Charindex(' ', Substring(ship, Charindex(' ', ship) + 1, Len(ship))) > 1 

The problem of the above code is that it doesn't matter what parameter I entered during the execution, it always gives the result as long as the parameter I entered is a valid table name in the database.

Right now I am wondering if I could create a parameter to enter a table name into FROM part, that way only when I enter outcomes it would display the result.

I tried to declare a table variable using the following code:

declare @ship_outcome table
(   final_work nvarchar(30)
)

insert into @ship_outcome (final_work)
select 
        left(ship, charindex(' ', ship) - 1) + ' ' + 
        replicate('*', charindex(' ', substring(ship, charindex(' ', ship) + 1, len(ship))) + 1 -2) + ' ' +
        reverse(left(reverse(ship), charindex(' ', reverse(ship)) - 1))
from outcomes
where charindex(' ', substring(ship, charindex(' ', ship) + 1, len(ship))) > 1;

select * from @ship_outcome

However I am not sure how to consolidate the table variable into the UDF. Please help.


Solution

  • You can also achieve the result using IF statement in Multi statement table valued function like mentioned below : -

    CREATE FUNCTION dbo.Shippad (@tbl NVARCHAR(30))
    RETURNS @t table
    (final_work nvarchar(30))
    AS
    begin
    if @tbl = 'outcomes'
    begin
          Insert into @t
          SELECT LEFT(ship, Charindex(' ', ship) - 1) + ' '
                 + Replicate('*', Charindex(' ', Substring(ship, Charindex(' ', ship) + 1, Len(ship))) + 1 -2)
                 + ' '
                 + Reverse(LEFT(Reverse(ship), Charindex(' ', Reverse(ship)) - 1)) as final_work 
          FROM   outcomes
          WHERE  Charindex(' ', Substring(ship, Charindex(' ', ship) + 1, Len(ship))) > 1 
    end
    return
    end
    

    Note - Performance of Multi statement table value function is horrible for large records. It is advisable to use Inline function by using @tbl = 'outcomes' in where clause in inline table value function like -

    CREATE FUNCTION dbo.Shippad (@tbl NVARCHAR(30))
    RETURNS TABLE
    AS
        RETURN
          SELECT LEFT(ship, Charindex(' ', ship) - 1) + ' '
                 + Replicate('*', Charindex(' ', Substring(ship, Charindex(' ', ship) + 1, Len(ship))) + 1 -2)
                 + ' '
                 + Reverse(LEFT(Reverse(ship), Charindex(' ', Reverse(ship)) - 1)) as final_work 
          FROM   outcomes
          WHERE  Charindex(' ', Substring(ship, Charindex(' ', ship) + 1, Len(ship))) > 1 and @tbl = 'outcomes'