Return table valued function return table structure like my actual table using Sql Server 2008? - sql

I have a table named tableincentive like below
create table tableincentive (entry_date date,ag_id int,us_id int,lo_id int,loin_id int,de_id int,dest_id int,incentive_amt decimal(18,2),le_id int,lion_id int,etc...)
And i have a table valued function named [dbo].[func_getdetails]
Create FUNCTION [dbo].[func_getdetails]
(
-- Add the parameters for the function here
#ason_date date
)
RETURNS
#tableincentive TABLE
(
-- Add the column definitions for the TABLE variable here
entry_date date,ag_id int,us_id int,lo_id int,loin_id int,de_id int,dest_id int,incentive_amt decimal(18,2),le_id int,lion_id int,etc...
)
AS
BEGIN
-- some long process then
insert into #tableincentive
select * from tableincentive;
end
My problem is the table tableincentive has 43 columns so i create a table valued function return tableincentive structure.I need return like my actual table.
that means in function
RETURNS
#tableincentive TABLE
(
-- Add the column definitions for the TABLE variable here
entry_date date,ag_id int,us_id int,lo_id int,loin_id int,de_id int,dest_id int,incentive_amt decimal(18,2),le_id int,lion_id int,etc...
)
AS
begin end
changed to
RETURNS tableincentive
AS
begin
end
or
RETURNS #tableincentive table like tableincentive
AS
begin
end

User Defined Functions need Static results. That means you have to define the return type while creating the function. So If you want to have a static result set, then probably you should opt for a stores Procedure.

Related

multiple selects from a function into a temp table

I have a function helper_function which I want to reuse
Passing a parameter to another function f_union_helper_functions where a string id_string with ids is passed
Split this string and iterate through all ids
calling the function and adding result to a temp table
return select from this table
Pseudo code:
create function f_union_helper_functions
(
#id_string varchar,
...
return table as
return
(
...
foreach id in #id_string
begin
select * from helper_function(id) into #tmp
end
select #tmp
)
This code above is far from being complete/correct. I just want to combine the concepts of iterating and union into a temp table and return it. How can I achieve that?
Here is the way I solved it:
ALTER FUNCTION [dbo].[f_union_helper_functions]
(
#id_string NVARCHAR(1024)
)
RETURNS TABLE
AS
RETURN
(
SELECT * FROM [dbo].[fnSplit](#id_string, ',') c CROSS APPLY [dbo].[helper_function](c.item)
)
If you got SQLServer >= 2016 you can use STRING_SPLIT instead of [fnSplit], which I got from here https://kishsharma.wordpress.com/2013/08/20/sql-server-user-defined-function-to-split-the-string-by-special-char/

Table-valued function that takes table as parameter and performs join

I use SQL server 2016.
I want to write a function that takes a table as a parameter and then performs a join on that table with another table.
I have declared the following type:
CREATE TYPE WorklistTable AS TABLE (WorklistId int NOT NULL)
Then I use it in a lot of functions that do selects based on certain conditions
CREATE FUNCTION [dbo].[fnGetSomeData] (
#WorklistIds WorklistTable readonly
)
RETURNS TABLE
AS RETURN
(
select WorklistId, wlu.UserId
from #WorklistIds
join [dbo].[WorklistUser] wlu on wlu.WorklistId = #WorklistIds.worklistId
-- the rest is omitted
);
I get the following error:
Must declare the scalar variable "#WorklistIds".
I tried to declare the variable, but I got an error:
The variable name '#WorklistIds' has already been declared. Variable names must be unique within a query batch or stored procedure.
You should use aliases when you are joing to table variable.
CREATE FUNCTION [dbo].[fnGetSomeData] (
#WorklistIds WorklistTable readonly
)
RETURNS TABLE
AS RETURN
(
select WorklistId, wlu.UserId
from #WorklistIds t
join [dbo].[WorklistUser] wlu on wlu.WorklistId = t.worklistId
-- the rest is omitted
);
You can't directly use the #Table name when referencing a column within a table variable. You either need to alias the table or wrap it in square brackets:
select WorklistId, wlu.UserId
from #WorklistIds As W
join [dbo].[WorklistUser] wlu on wlu.WorklistId = W.worklistId
Or
select WorklistId, wlu.UserId
from #WorklistIds
join [dbo].[WorklistUser] wlu on wlu.WorklistId = [#WorklistIds].worklistId

SQL - create function that will take a table variable as an input

I'm having trouble writing a function that will take a table variable as an input and return the total number of rows in that table.
Here is my try:
CREATE FUNCTION fTableRows( #table TABLE )
RETURNS INT AS
BEGIN
RETURN( SELECT COUNT(*) FROM #table )
END
If you do this in SQL server 2008 + you have use user defined data type - table.
Good explanation can be found here: Pass table as parameter into SQL Udf
CREATE FUNCTION getTableRows
(
#TableName VARCHAR(30)
)
RETURNS INT AS
BEGIN
RETURN( SELECT COUNT(*) FROM #TableName)
END

Returning or outputting a #tableVariable in SQL

Is it possible to return or output a #tableVariable in SQL Server?
For example for the following stored procedure, how do I return the #TSV table variable?
ALTER PROCEDURE MyStoredProdecure
#Parameter1 INT,
#Parameter2 INT
AS
BEGIN
DECLARE #TSV TABLE
(
Transition_Set_Variable_ID INT,
Passed BIT
)
INSERT INTO #TSV
{ some data }
END
You cannot do it directly. Table variables are valid for READONLY input.
If you have no other data being returned from the stored procedure, you can select from the #TSV at the end and have the caller capture the output, e.g.
ALTER PROCEDURE MyStoredProdecure
#Parameter1 INT,
#Parameter2 INT
AS
BEGIN
DECLARE #TSV TABLE
(
Transition_Set_Variable_ID INT,
Passed BIT
)
INSERT INTO #TSV
{ some data }
SELECT * FROM #TSV
END
Caller
DECLARE #outerTSV TABLE
(
Transition_Set_Variable_ID INT,
Passed BIT
);
insert into #outerTSV
exec MyStoredProdecure 1, 2;
Alternatively, if the SP is really as simple as you showed, turn it into a table valued function instead.
No, but you can write a table valued function that returns a table.
create function MyTVF
#Parameter1 INT,
#Parameter2 INT
returns #tsv table
(
Transition_Set_Variable_ID INT,
Passed BIT
)
AS
BEGIN
INSERT INTO #TSV
{ some data }
return
END
Table Valued Parameters can only be used for input only, not output.
Depending on what your end goal is, here are some options:
change the sproc to a table-valued function to return a TABLE, that can then be used inline in another statement
simply SELECT the data from the #TSV table var at the end of your sproc
return an XML OUTPUT parameter (get a grubby feeling suggesting this, but just to highlight one way to return multiple rows actually using an OUTPUT parameter)
If you go for a Table Valued Function, ideally create an inline one if it is simple as it looks in your case:
e.g.
CREATE FUNCTION dbo.Func()
RETURNS TABLE
AS
RETURN
(
SELECT Something
FROM Somewhere
WHERE x = 1
)

T-SQL Foreach Loop

Scenario
I have a stored procedure written in T-Sql using SQL Server 2005.
"SEL_ValuesByAssetName"
It accepts a unique string "AssetName".
It returns a table of values.
Question
Instead of calling the stored procedure multiple times and having to make a database call everytime I do this, I want to create another stored procedure that accepts a list of all the "AssetNames", and calls the stored procedure "SEL_ValueByAssetName" for each assetname in the list, and then returns the ENTIRE TABLE OF VALUES.
Pseudo Code
foreach(value in #AllAssetsList)
{
#AssetName = value
SEL_ValueByAssetName(#AssetName)
UPDATE #TempTable
}
How would I go about doing this?
It will look quite crippled with using Stored Procedures. But can you use Table-Valued Functions instead?
In case of Table-Valued functions it would look something like:
SELECT al.Value AS AssetName, av.* FROM #AllAssetsList AS al
CROSS APPLY SEL_ValuesByAssetName(al.Value) AS av
Sample implementation:
First of all, we need to create a Table-Valued Parameter type:
CREATE TYPE [dbo].[tvpStringTable] AS TABLE(Value varchar(max) NOT NULL)
Then, we need a function to get a value of a specific asset:
CREATE FUNCTION [dbo].[tvfGetAssetValue]
(
#assetName varchar(max)
)
RETURNS TABLE
AS
RETURN
(
-- Add the SELECT statement with parameter references here
SELECT 0 AS AssetValue
UNION
SELECT 5 AS AssetValue
UNION
SELECT 7 AS AssetValue
)
Next, a function to return a list AssetName, AssetValue for assets list:
CREATE FUNCTION [dbo].[tvfGetAllAssets]
(
#assetsList tvpStringTable READONLY
)
RETURNS TABLE
AS
RETURN
(
-- Add the SELECT statement with parameter references here
SELECT al.Value AS AssetName, av.AssetValue FROM #assetsList al
CROSS APPLY tvfGetAssetValue(al.Value) AS av
)
Finally, we can test it:
DECLARE #names tvpStringTable
INSERT INTO #names VALUES ('name1'), ('name2'), ('name3')
SELECT * FROM [Test].[dbo].[tvfGetAllAssets] (#names)
In MSSQL 2000 I would make #allAssetsList a Varchar comma separated values list. (and keep in mind that maximum length is 8000)
I would create a temporary table in the memory, parse this string and insert into that table, then do a simple query with the condition where assetName in (select assetName from #tempTable)
I wrote about MSSQL 2000 because I am not sure whether MSSQL 2005 has some new data type like an array that can be passed as a literal to the SP.