Solved

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

Posted on 2011-03-13
10
360 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
  • 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
 
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
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 
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 500 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

NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

Question has a verified solution.

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

Suggested Solutions

PL/SQL can be a very powerful tool for working directly with database tables. Being able to loop will allow you to perform more complex operations, but can be a little tricky to write correctly. This article will provide examples of basic loops alon…
Ever needed a SQL 2008 Database replicated/mirrored/log shipped on another server but you can't take the downtime inflicted by initial snapshot or disconnect while T-logs are restored or mirror applied? You can use SQL Server Initialize from Backup…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

943 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now