How to call Stored Procedure from within a TVF? - sql

I'd like to utilise an already written stored procedure having parameters and temp tables for a report with Power BI (DirectQuery).
I've tried to do so via table-valued function as shown below:
CREATE FUNCTION [rpt].[ufnPBI0002_KPI]
(#YearMonth nvarchar(20), -- = '2017-12'
#Products nvarchar(50), -- = '2,7,8'
#Regions nvarchar(50) -- = '1'
)
-----------------------------------------------------------------------
-- Return type
-----------------------------------------------------------------------
RETURNS TABLE
-----------------------------------------------------------------------
-- Begin
-----------------------------------------------------------------------
AS
BEGIN
-----------------------------------------------------------------------
-- Declare return table
-----------------------------------------------------------------------
DECLARE #Result AS TABLE
(
SalesRegionId INT
,TotalCAcount INT
,EffectiveCAcount INT
,NewCA INT
,Plan_Total_CA_count INT
,Plan_eCA_Count_All INT
,Plan_CA_Intake INT
,Plan_CA_PJ_count INT
,Plan_NV_Prod_PJ INT
,Plan_Avg_NV_All_per_eCA INT
,BusinessLoanSpecialistCount INT
,ProfiJuniors INT
,ActiveCAcount INT
,TerminatedCAcount INT
,NewNV INT
,NewNVPJ INT
,AvgNVeCA INT
,AvgNVProfiJuniors INT
)
--------------------------------------------------------------------------
-- Handle stored procedure result
--------------------------------------------------------------------------
INSERT INTO #Result
EXEC [rpt].[MR0002_KPI] #YearMonth, #Products, #Regions
--------------------------------------------------------------------------
-- Return the result
--------------------------------------------------------------------------
SELECT * FROM #Result
RETURN;
-----------------------------------------------------------------------
-- END
-----------------------------------------------------------------------
END
Which returns
Msg 102, Level 15, State 31, Procedure ufnPBI0002_KPI, Line 68 [Batch Start Line 0]
Incorrect syntax near 'BEGIN'
I think it would not be possible to call a stored procedure from a TFV, but would really appreciate any hints, how to utilise parametric stored procedure with PBI.

You can not call stored procedures from within a Function
User-defined functions cannot call a stored procedure, but can call an extended stored procedure.
Change the function to a stored procedure

When it comes to SSRS data sources, you do not have to use a function in your case, bit can just directly use a stored procedure:
EXEC [rpt].[MR0002_KPI] #YearMonth, #Products, #Regions
Just refresh a dataset, it should be able to detect available columns returned by SP.
Moreover, your initial approach would result (if TVM allows SP) to unnecessary inserts to #Result table variable, so it could cause extra load on TEMPDB

Related

How to use stored procedure return value into an insert statement?

I have a stored procedure like
CREATE PROCEDURE GetSerial (#param1 int, #param2 int)
AS
BEGIN
-- do some insert/updates, so I can't use function
DECLARE #value AS int;
SET #value = 3;
return #value;
END
Now I declare a table variable
DECLARE #Serials AS TABLE
(
ID int,
Value int
)
Now I wanna fill this table like
INSERT INTO #Serials (ID, Value)
SELECT 1, GetSerial(1,2) -- *How can I call this?
So, can anyone help me how can i call the GetSerial stored procedure inside the SELECT statement to fill my table?
I recommend you avoid getting into this pattern/thinking, because stored procedures only return INTs, and those ints are really intended to describe how well the operation went, not a result/data from the operation. Example: 0 => failed, 1=> succeeded. Not GetAgeInYears() => 29
https://learn.microsoft.com/en-us/sql/relational-databases/stored-procedures/return-data-from-a-stored-procedure?view=sql-server-2017 has a lot of info and concrete examples but in your specific case you'd need to execute the procedure and capture the result code into a variable then insert that:
DECLARE #ret INT;
EXEC #ret = GetSerial(1,2);
INSERT INTO #Serials VALUES(1, #ret);
Really you'd be better off using an output parameter or resultset if you have many values to return. See the above link for more

SQL - Save results from stored procedure to a variable

I have a stored procedure that I cannot change. And it returns a select value (integer).
It insert some values and return the new id - the last line of the stored procedure:
SELECT #newID
I am using the new ID but I don't want to display that value when I run the stored procedure.
So I use the following:
DECLARE #test INT
EXEC #test = Pr_My_Procedure 'NewGroupName'
SELECT #test
This executes successfully, but my variable #test is always = 0 when the actual value created and return for the stored procedure is an actual id number.
Why is my variable is not being assigned?
I have a work around (which is not really what I wanted but it works:
1 DECLARE #NewGroupID INT
2 EXEC Pr_My_Procedure 'NewGroupName'
3 SET #NewGroupID = (SELECT GroupID FROM DB..Groups WHERE GroupName = 'NewGroupName')
This works, but when running the stored procedure, I still get the GroupID generated being return on the results (line 2). I don't want to see that.
Is it possible to NOT return that select result from the procedure?
Thanks all for any advise!
When you do
exec #p = StoredProc
... you are dealing with the return value of the proc, not the result set of the proc. The default return value of a procedure is zero so that if you do not do an explicit RETURN in your procedure, it returns 0.
You can change the procedure to RETURN your ID, or add an output parameter.
-- Procedure which RETURNS the ID
create procedure StoredProc_WithReturn
as
return 10;
go
-- Procedure which uses output parameter instead.
create procedure StoredProc_WithOutput
#p int output
as
select #p = 12;
go
-- Now test both ways of returning a value
declare #p int = 0,
#po int = 0;
exec #p = StoredProc_WithReturn;
select #p;
exec StoredProc_WithOutput #po output;
select #po;
Since you cannot change the procedure, you can insert the result set of the procedure into a table, temporary table or table variable like so
create procedure StoredProc_WithSelect
as
select 10;
go
declare #pt table (a int);
insert #pt
exec StoredProc_WithSelect;
select a from #pt;
If you don't see result, you can use PRINT instead of SELECT. Try this:
DECLARE #test INT
EXEC #test = Pr_My_Procedure 'NewGroupName'
PRINT #test

unqiueidenfitier is not compatible with type int SQL Server Procedure

I have the following procedure for inserting into a user table:
-- ================================================
-- Template generated from Template Explorer using:
-- Create Procedure (New Menu).SQL
--
-- Use the Specify Values for Template Parameters
-- command (Ctrl-Shift-M) to fill in the parameter
-- values below.
--
-- This block of comments will not be included in
-- the definition of the procedure.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Andy Armstrong
-- Create date:
-- Description:
-- =============================================
CREATE PROCEDURE db_SignupAddLogin
-- Add the parameters for the stored procedure here
#LoginName VARCHAR(15),
#LoginPassword VARCHAR(15)
AS
BEGIN
DECLARE #GUID UNIQUEIDENTIFIER
SET #GUID = NEWID();
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
INSERT INTO tblMemberLogin
(
UserID,
LoginName,
LoginPassword
)
VALUES
(
#GUID,
#LoginName,
#LoginPassword
)
RETURN #GUID
END
GO
However when I execute it I get the following error:
Msg 206, Level 16, State 2, Procedure db_SignupAddLogin, Line 34
Operand type clash: uniqueidentifier is incompatible with int
I cannot quite workout why as i am not referencing an int anywhere.
My Schema for tblMemberLogin looks like this:
UserID(PK,uniqueidentifier,notnull)
LoginName(nchar(15),not null)
LoginPassword(nchar(15),not null)
Please help!
RETURN can only be used with an int. You can simply use a SELECT query to retrieve the value of variable #GUID.
Reference: http://technet.microsoft.com/en-us/library/ms174998(v=sql.110).aspx
get rid of RETURN #GUID and you should be good to go.
In SQL Server, stored procedures may only return integer values. SQL Server RETURN
If you want to return data from a stored procedure other than an integer, you can use an output parameter: Returning Data from Stored Procedures
You declare the output parameter along with your input parameters:
CREATE PROCEDURE CREATE PROCEDURE db_SignupAddLogin
-- Add the parameters for the stored procedure here
#LoginName VARCHAR(15),
#LoginPassword VARCHAR(15),
#NewGuid UNIQUEIDENTIFIER OUTPUT
AS
BEGIN
SET #NewGuid = NEWID();
-- rest of procedure
END
And then use the output parameter:
DECLARE #NewLoginGuidFromSP UNIQUEIDENTIFIER
EXECUTE db_SignupAddLogin 'Username', 'password', #NewGuid = #NewLoginGuidFromSP OUTPUT;

Stored Procedure Output

I've got two stored procedures:
SP1
CREATE PROCEDURE GetAge
#Birthday datetime,
#BirthDayAge INT OUTPUT
AS
SELECT #BirthDayAge = YEAR(GETDATE()-DATEPART(dy, #Birthday) + 1)-YEAR(#Birthday);
SP2
CREATE PROCEDURE AgeProc
#Age int
AS
DECLARE #BirthDayAge INT;
EXEC GetAge #Age, #BirthDayAge OUTPUT
SELECT ... FROM ... WHERE #BirthdayAge = #Age;
For some reason or other, no results are being returned in the second procedure when tested. Am I doing something wrong in either of the stored procedures?
WHERE #BirthdayAge = #Age;
you are comparing 2 variables.
Shouldnt one of this be a table column?
also, you are passing an integer to a datetime, that may cause issues

can we have a stored procedure with output parameters and return statement?

Can a stored procedure have output parameters and return statement? If so can anybody give me a simple example.thank you all.
Stored procedure can return integer type only in a return statement and can have any number of out parameters. See this for references supporting this.
Simplest eg of stored procedure
Return integer value from SP
CREATE procedure [sys].[sp_name]
(
#var1 bit = 0,
#publisher smallint
)
AS
BEGIN
IF #var1<> 0
RETURN (#publisher )
END
Using Out Parameter
CREATE PROCEDURE GetImmediateManager
#employeeID INT,
#managerID INT OUTPUT
AS
BEGIN
SELECT #managerID = ManagerID
FROM HumanResources.Employee
WHERE EmployeeID = #employeeID
END
You can use Transactions, Exception handling(try Catch), DDL and DML Queries, calling another stored procedure within one stored procedures and many more operations.
Please comments for more functionalities supported in stored procedure
If you mean the standard RETURN statement that gives an integer then yes
If you mean a UDF RETURN , then no. But a stored proc can have a normal SELECT
You are free to use both OUTPUT params and a single RETURN value:
CREATE PROCEDURE RaiseToPower (
#IN INT,
#OUT INT OUTPUT
)
AS
DECLARE #POWER INT
SET #POWER = 3
SET #OUT = POWER(#IN, #POWER)
RETURN #POWER
GO
/**/
DECLARE #POW INT, #RESULT INT
EXEC #POW = dbo.RaiseToPower 2, #RESULT OUTPUT
SELECT 2, 'raised to', #POW, 'is', #RESULT
>> 2 raised to 3 is 8
No. It is either a stored procedure or a scalar function.
A scalar function returns a value and takes 0 to n in parameters.
A stored procedure can take from 0 to n input parameters and can have 0 to n output parameters.