Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Can I reuse UDF returned value in a SQL Stored Procedure within the same Stored Procedure ?

Posted on 2011-03-13
10
Medium Priority
?
383 Views
Last Modified: 2012-05-11
I have a sproc for returning LaborHours that has a User Defined Function for a row source which returns a sum of Fringe costs, usually 4 fringe rows for every LaborHours row in sproc. I want to then add the LaborHours with the sum of the Fringe costs as another column but I have to rerun the Function and it makes the query time go from 7 seconds to more than twice that. Seems to me if I already calculated the Fringe costs I could store them in a variable and then add the variable to the LaborHours for a total column.

Here is an excerpt from my sproc:

SELECT
hs.TS_LN_KEY
hs.LAB_CST_AMT AS TotalLaborCost,
dbo.fn_Eng_OaFringeTotals(hs.TS_LN_KEY) AS TotalFringeCosts,     --This returns the sum of fringe costs,
dbo.fn_Eng_OaFringeTotals(hs.TS_LN_KEY) + hs.LAB_CST_AMT  AS TotalCosts,   --have to rerun the function and add it to the laborcost

FROM ....etc

Open in new window


Is ther a way to assign the fringe costs to a variable and reuse it?
 
0
Comment
Question by:AkAlan
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 2
10 Comments
 
LVL 11

Expert Comment

by:JoeNuvo
ID: 35125050
take a look at this one to see if any comment might good to apply for you
http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/Q_26818174.html

and with the same way of my answer, your query should be like this

SELECT
        <other field lists>,
        Sub.TotalLaborCost * Sub.TotalFringeCosts AS TotalCosts
FROM (
      SELECT
      hs.TS_LN_KEY
      hs.LAB_CST_AMT AS TotalLaborCost,
      dbo.fn_Eng_OaFringeTotals(hs.TS_LN_KEY) AS TotalFringeCosts,
      .....
      FROM ....etc
) Sub
0
 
LVL 19

Expert Comment

by:Bhavesh Shah
ID: 35126820

Hi,

What I suggest is that, you can use temporary table.

like

SELECT
hs.TS_LN_KEY
hs.LAB_CST_AMT AS TotalLaborCost,
dbo.fn_Eng_OaFringeTotals(hs.TS_LN_KEY) AS TotalFringeCosts,     --This returns the sum of fringe costs,
dbo.fn_Eng_OaFringeTotals(hs.TS_LN_KEY) + hs.LAB_CST_AMT  AS TotalCosts,   --have to rerun the function and add it to the laborcost

INTO #TempTable

FROM ....etc



If above query is inside procedure then you no need to drop that table explicitly.

else you can use

DROP TABLE #TempTable



- Bhavesh
0
 
LVL 6

Author Comment

by:AkAlan
ID: 35128963
Joe, that looks promising, I'll try it out later today.

Brichsoft, I don't see how your solution keeps from running the same function twice.
0
Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

 
LVL 19

Expert Comment

by:Bhavesh Shah
ID: 35135335
Hi,

See.I'm assuming, you calling one function twice and that you wanted to avoid..

If so then.....

This will be your 1st Query.

SELECT
hs.TS_LN_KEY,
hs.LAB_CST_AMT AS TotalLaborCost,
dbo.fn_Eng_OaFringeTotals(hs.TS_LN_KEY) AS TotalFringeCosts,     --This returns the sum of fringe costs,
Other columns

into #Temp

FROM ....etc


This will be your 2nd Query.

SELECT TS_LN_KEY, TotalLaborCost, (TotalLaborCost + TotalFringeCosts) TotalCosts
FROM #Temp


- Bhavesh
0
 
LVL 6

Author Comment

by:AkAlan
ID: 35139197
Bhavesh, thanks for clearing that up. I still have not been able to play with either soultion, I will soon and see which one works best.

Cheers, Alan
0
 
LVL 6

Author Comment

by:AkAlan
ID: 35200875
Joe, I tried your solution and while it worked ok, it didn't really speed the time the query took to run, which is what I am looking for.

Bhavesh, I'm not familiar with temp tables so maybe there is something more that I need to do but when I try the following code, I get "There is already an object named '#Temp' in the database."


Alter PROCEDURE [dbo].[spSelectENG_OverAndAboveSummary_Test]
(@OA_Nr varchar(5) = NULL)
--@Engineer varchar(6) = NULL)    --Must use a varchar to use wildcard, 


AS 
CREATE TABLE #Temp(OaNumber char(5),ProjectDescription Varchar(MAX),tp money,tt money, tl Money)
SELECT				oap.OANumber,
				    oap.ProjectDescription,
				    dbo.fn_Eng_OaPurchaceTotals(oap.OANumber) AS TotalPurchases, 
				    dbo.fn_Eng_OaTravelTotals(oap.OANumber) AS TotalTravel,
				    dbo.fn_Eng_OaLaborTotals(oap.OANumber) AS TotalLabor
				    
				    INTO #Temp
					
				    FROM 
					
				dbo.ENG_OverAndAboveProjects    oap 
				
				WHERE oap.OANumber = @OA_Nr 
					
				SELECT oap.OANumber FROM #Temp  --There is already an object named '#Temp' in the database.

Open in new window

                       
0
 
LVL 19

Expert Comment

by:Bhavesh Shah
ID: 35204203
Hi Alan,

As you created

CREATE TABLE #Temp(OaNumber char(5),ProjectDescription Varchar(MAX),tp money,tt money, tl Money)

so you no need to use INTO #Temp

you need to use below query.


- Bhavesh
Alter PROCEDURE [dbo].[spSelectENG_OverAndAboveSummary_Test]
(@OA_Nr varchar(5) = NULL)
--@Engineer varchar(6) = NULL)    --Must use a varchar to use wildcard, 


AS 
CREATE TABLE #Temp(OaNumber char(5),ProjectDescription Varchar(MAX),tp money,tt money, tl Money)
insert into #Temp
SELECT                          oap.OANumber,
                                    oap.ProjectDescription,
                                    dbo.fn_Eng_OaPurchaceTotals(oap.OANumber) AS TotalPurchases, 
                                    dbo.fn_Eng_OaTravelTotals(oap.OANumber) AS TotalTravel,
                                    dbo.fn_Eng_OaLaborTotals(oap.OANumber) AS TotalLabor
                                    
                                     
                                        
                                    FROM 
                                        
                                dbo.ENG_OverAndAboveProjects    oap 
                                
                                WHERE oap.OANumber = @OA_Nr 
                                        
                                SELECT oap.OANumber FROM #Temp  --There is already an object named '#Temp' in the database.

Open in new window

0
 
LVL 19

Accepted Solution

by:
Bhavesh Shah earned 2000 total points
ID: 35204263
Hi,

Just for information.

Below query will create physical table in database.

SELECT
            oap.OANumber,
            oap.ProjectDescription,
            dbo.fn_Eng_OaPurchaceTotals(oap.OANumber) AS TotalPurchases,
            dbo.fn_Eng_OaTravelTotals(oap.OANumber) AS TotalTravel,
            dbo.fn_Eng_OaLaborTotals(oap.OANumber) AS TotalLabor
 INTO NewTable
 FROM
           dbo.ENG_OverAndAboveProjects    oap
 WHERE oap.OANumber = @OA_Nr



Below query will create temporary table in database, this table will create in tempdb database

SELECT
            oap.OANumber,
            oap.ProjectDescription,
            dbo.fn_Eng_OaPurchaceTotals(oap.OANumber) AS TotalPurchases,
            dbo.fn_Eng_OaTravelTotals(oap.OANumber) AS TotalTravel,
            dbo.fn_Eng_OaLaborTotals(oap.OANumber) AS TotalLabor
 INTO #NewTable
 FROM
           dbo.ENG_OverAndAboveProjects    oap
 WHERE oap.OANumber = @OA_Nr

 

More information on temporary table.

Types of Temporary tables

There are two types of temporary data types. They are namely Local and global. Let me first give you and example to start the temporary table. Following example is taken from Books on Line of Microsoft® SQL Server™ 2000.

"The two types of temporary tables, local and global, differ from each other in their names, their visibility, and their availability. Local temporary tables have a single number sign (#) as the first character of their names; they are visible only to the current connection for the user; and they are deleted when the user disconnects from instances of Microsoft® SQL Server™ 2000. Global temporary tables have two number signs (##) as the first characters of their names; they are visible to any user after they are created; and they are deleted when all users referencing the table disconnect from SQL Server" 1

"For example, if you create a table named employees, the table can be used by any person who has the security permissions in the database to use it, until the table is deleted. If you create a local temporary table named #employees, you are the only person who can work with the table, and it is deleted when you disconnect. If you create a global temporary table named ##employees, any user in the database can work with this table. If no other user works with this table after you create it, the table is deleted when you disconnect. If another user works with the table after you create it, SQL Server deletes it when both of you disconnect."2

Note: 1,2 above is taken from the book on line sub heading Creating and Modifying

Unlike in the access days, you do not have to delete these temporary tables manually, instead you can rely SQL Server to do it automatically.
0
 
LVL 19

Expert Comment

by:Bhavesh Shah
ID: 35204273
Hi,

I am not sure, this will improve performance.
If you can share your function code then, might experts can give you suggestion for better approach.


- Bhavesh
0
 
LVL 11

Expert Comment

by:JoeNuvo
ID: 35204312
If your function doesn't contain complex query/query working with huge dataset.
Reduce 1 call may not effect much of performance. (in profiler, CPU maybe the same, but maybe reduce READ)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes how to use the timestamp of existing data in a database to allow Tableau to calculate the prior work day instead of relying on case statements or if statements to calculate the days of the week.
In part one, we reviewed the prerequisites required for installing SQL Server vNext. In this part we will explore how to install Microsoft's SQL Server on Ubuntu 16.04.
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…

618 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question