cannot set the result of a select statement to a variable : Select statements included within a function cannot return data to a client.

I am trying to set a User function to get alphas, Betas and R2 from a linear regression within sql.

I can get the data through the select statement, but it fails to register as a Function, stating 

"Select statements included within a function cannot return data to a client."

I have tried to Set the result of the select statement into the @Beta vaiable but that too doesnt work.


Create Function MasterDB.Uf_AlphaBetaR2(@X int,@Y int)
  RETURNS float
AS
Begin;
DECLARE @Beta float;
WITH 
some_table( x, y) AS

SELECT     Performance_1.[Return] AS x, Performance_2.[Return] AS y
FROM         dbo.Performance INNER JOIN
                      dbo.Performance AS Performance_2 ON dbo.Performance.Date = Performance_2.Date INNER JOIN
                      dbo.Performance AS Performance_1 ON dbo.Performance.Date = Performance_1.Date
WHERE     (dbo.Performance.ID = 70305 OR
                      dbo.Performance.ID = @X) AND (dbo.Performance.[Return] IS NOT NULL) AND (Performance_1.ID = @Y) AND (Performance_2.ID = @X)
),

average_estimate AS
(   SELECT avg(x) as xbar
,avg(y) as ybar
    FROM some_table
),

beta_estimate AS
(   SELECT     CASE COALESCE(SUM((x-xbar)*(x-xbar)),0)
                    WHEN 0 THEN NULL
                    ELSE SUM((x-xbar)*(y-ybar)) / SUM((x-xbar)*(x-xbar))
                END AS Beta
FROM        some_table pd
Cross JOIN  average_estimate pa
),

alpha_estimate AS 
(   SELECT ybar - xbar * pb.Beta AS Alpha
FROM beta_estimate pb
Cross JOIN average_estimate pa
), 

sumsquares_estimate AS
(   SELECT SUM((y-ybar)*(y-ybar)) AS SS_tot
          ,SUM((y-(Alpha+Beta*x)) * (y-(Alpha+Beta*x))) AS SS_err
    FROM alpha_estimate pa
    cross JOIN beta_estimate pb
    Cross JOIN some_table 
    Cross JOIN average_estimate ae            
)
SELECT  Beta
FROM alpha_estimate pa
Cross JOIN beta_estimate pb
Cross JOIN sumsquares_estimate ss  ;


RETURN @Beta;
END;

July 5th, 2013 12:57pm

I have tried to Set the result of the select statement into the @Beta vaiable but that too doesnt work.

Unfortunately, statements like the above provide little information.  Be explicit.  If an error occurs provide the exact and entire error message. 

That said, your function is defined to return a scalar value.  So you will need to write your query to capture the correct value in a variable and return it.  Your select statement apparently generates a 1 X 1 resultset; though they may appear similar, this resultset is not the same as a scalar value.  In addition, the original error message tells you of a limitation of UDFs (one of many, I'll add).  You cannot return a resultset from a UDF as you would from a stored procedure.  The resultset of the select statement in your function must be consumed within the function. 

While rewriting, I suggest you remove the logic that serves no purpose.  This includes the sumsquares_estimate and alpha_estimate ctes.  Your use of cross joins is rather unique.  It may be easier to rewrite if you first write a script to capture the result in a variable and then move it into a UDF; that approach will allow you to avoid many syntax issues as well as try different approaches/techniques to find the best one for your circumstances. 

Free Windows Admin Tool Kit Click here and download it now
July 5th, 2013 2:42pm

I'm assuming that a set of data is coming back from that last sql statement as opposed to a single value.

Would returning a table of data type float not suffice?

Try this:

Create Function MasterDB.Uf_AlphaBetaR2(@X int,@Y int)
   RETURNS @Beta TABLE 
(
    -- Columns returned by the function
    Beta float
 )

 AS
 Begin;
 
 WITH 
 some_table( x, y) AS
( 
SELECT     Performance_1.[Return] AS x, Performance_2.[Return] AS y
FROM         dbo.Performance INNER JOIN
                       dbo.Performance AS Performance_2 ON dbo.Performance.Date = Performance_2.Date INNER JOIN
                       dbo.Performance AS Performance_1 ON dbo.Performance.Date = Performance_1.Date
WHERE     (dbo.Performance.ID = 70305 OR
                       dbo.Performance.ID = @X) AND (dbo.Performance.[Return] IS NOT NULL) AND (Performance_1.ID = @Y) AND (Performance_2.ID = @X)
),

 average_estimate AS
(   SELECT avg(x) as xbar
,avg(y) as ybar
     FROM some_table
),

 beta_estimate AS
(   SELECT     CASE COALESCE(SUM((x-xbar)*(x-xbar)),0)
                     WHEN 0 THEN NULL
                     ELSE SUM((x-xbar)*(y-ybar)) / SUM((x-xbar)*(x-xbar))
                 END AS Beta
FROM        some_table pd
Cross JOIN  average_estimate pa
),

 alpha_estimate AS 
(   SELECT ybar - xbar * pb.Beta AS Alpha
FROM beta_estimate pb
Cross JOIN average_estimate pa
), 

 sumsquares_estimate AS
(   SELECT SUM((y-ybar)*(y-ybar)) AS SS_tot
           ,SUM((y-(Alpha+Beta*x)) * (y-(Alpha+Beta*x))) AS SS_err
     FROM alpha_estimate pa
     cross JOIN beta_estimate pb
     Cross JOIN some_table 
     Cross JOIN average_estimate ae            
)
INSERT @Beta 
SELECT  Beta
FROM alpha_estimate pa
Cross JOIN beta_estimate pb
Cross JOIN sumsquares_estimate ss  ;


RETURN ;
 END;

July 5th, 2013 3:06pm

Your select statement at the end should be

select @Beta = beta

from

Free Windows Admin Tool Kit Click here and download it now
July 5th, 2013 4:15pm

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics