2

I have this SQL Server query:

DECLARE @HoursUsed float

SELECT COLUMN_A 
,(SELECT (@HoursUsed = (SELECT dbo.fn_GetProjectHoursUsed(Project.fg_projectId))) 
,@HoursUsed*100
,@HoursUsed*200
FROM Project, OTHER_TABLES)

I need the result from the function to be added to the variable because I will need it in several places later in the query.

The DB function is working fine by itself. If I remove the variable from the SELECT it works fine.

If I try to run the query like this it throws errors like:

Incorrect syntax near =, ), as.

The entire query uses this function several times and I have performance issues with it. So that's why I want to put the value in a variable and call the function only once.

I appreciate your help

Edit: Here is the complete query.

DECLARE @HoursUsed float

SELECT  DISTINCT
    Account.Name as AccountName
    ,Project.FG_SalesRepIdName as Rep
    ,Project.fg_Name as ProjectName
    ,Project.fg_projectId

,(SELECT dbo.fn_GetProjectPriceRate(Project.fg_projectId)) as ProjectPriceRate

,(
SELECT SalesOrder.totalAmount FROM fg_Project, SalesOrder
        WHERE fg_Project.fg_orderId = SalesOrder.salesOrderId 
            AND fg_Project.fg_Name = Project.fg_Name
            AND fg_Project.fg_projectId = Project.fg_projectId
)/dbo.fn_GetProjectPriceRate(Project.fg_projectId) as TotalHours  
    --The total hours are found by division of the total price of the project     with the price rate
    ,(
    SELECT SalesOrder.totalAmount FROM fg_Project, SalesOrder
            WHERE fg_Project.fg_orderId = SalesOrder.salesOrderId 
                AND fg_Project.fg_projectId = Project.fg_projectId
    ) AS TotalAmount

    ,(SELECT @HoursUsed = dbo.fn_GetProjectHoursUsed(Project.fg_projectId)
        SELECT @HoursUsed
    ) as HoursUsed

    ,(
    (SELECT dbo.fn_GetProjectHoursUsed(Project.fg_projectId))
    /
        NULLIF(((SELECT SalesOrder.totalAmount FROM fg_Project, SalesOrder
            WHERE fg_Project.fg_orderId = SalesOrder.salesOrderId 
                AND fg_Project.fg_Name = Project.fg_Name
                AND fg_Project.fg_projectId = Project.fg_projectId
               )
        /
              NULLIF(dbo.fn_GetProjectPriceRate(Project.fg_projectId),0)
             ),0)
    )*100 as PercentHoursUsed
    ,(SELECT dbo.fn_GetProjectHoursBilled(Project.fg_projectId)) as HoursBilled
    ,(SELECT dbo.fn_GetProjectHoursBilled(Project.fg_projectId))
     *
     (SELECT dbo.fn_GetProjectPriceRate(Project.fg_projectId)) as AmountBilled



FROM Account, fg_Project as Project, fg_ProjectElement, Product

WHERE       Account.accountId = Project.fg_regardingId
    AND Project.fg_ProjectId = fg_ProjectElement.fg_projectElemenstId
    AND fg_ProjectElement.fg_ProductId = Product.ProductId
    AND Product.ProductNumber = 'WEB DEV'
3
  • The entire query uses this function several times and I have performance issues with it. So that's why I want to put the value in a variable and call the function only once. Commented Jul 21, 2011 at 23:35
  • Are you using it in a stored procedure? Commented Jul 21, 2011 at 23:39
  • No, i use it for a query in SSRS Report. Commented Jul 21, 2011 at 23:40

6 Answers 6

2

I'm partially guessing your schema, but maybe using a temp table would help ? e.g. something like :

DECLARE @HoursUsedTable TABLE (ProjectId int primary key, HoursUsed float)
INSERT @HoursUsedTable (ProjectId, HoursUsed) 
SELECT fg_projectId, dbo.fn_GetProjectHoursUsed(p.fg_projectId) from Project p


SELECT COLUMN_A, 
hu.HoursUsed,
hu.HoursUsed * 100,
hu.HoursUsed * 200
FROM Project p JOIN @HoursUsedTable hu ON hu.ProjectId = p.fg_projectId
, OTHER_TABLES

Note also that using scalar valued UDFs in some contexts can lead to peformance issues (I'm guessing your UDF returns a scalar ?) - better to use an inline table valued UDF if possible.

Sign up to request clarification or add additional context in comments.

Comments

2

You can use a subselect like this:

SELECT
  *,
  HoursUsed * 100 AS Hours100
  HoursUsed * 200 AS Hours200
FROM (
  SELECT
    HoursUsed = dbo.fn_GetProjectHoursUsed(Project.fg_projectId),
    other columns
  FROM Project, other tables
  …
) s

No variable is required.

Comments

1

Try this, it will only use the function once for every line and you can refer to the function result

SELECT COLUMN_A, a.HoursUsed, a.HoursUsed*100, a.HoursUsed*200 
FROM Project p CROSS APPLY 
(SELECT  dbo.fn_GetProjectHoursUsed(P.fg_projectId) HoursUsed) a 

Comments

0

Try this:

SELECT @HoursUsed = dbo.fn_GetProjectHoursUsed(Project.fg_projectId)
...and rest of your query

3 Comments

I forgot to mention, this whole query, is a subquery for a column in another query.
mitte this is the correct solution, if your query still fails, you have a problem elsewhere in code which we don't have access to
I added the whole query to the question
0

This worked for me:

    DECLARE @HoursUsed float

    SELECT @HoursUsed = (SELECT dbo.fn_GetProjectHoursUsed(Project.fg_projectId))

Try removing the outer parans.

Comments

0

When you set a variable within the SELECT clause, the variable does not need its own SELECT keyword. The correct form should be:

DECLARE @HoursUsed float

SELECT COLUMN_A,@HoursUsed = dbo.fn_GetProjectHoursUsed(Project.fg_projectId) 
,@HoursUsed*100
FROM SOME_TABLES

If fn_GetProjectHoursUsed() has a table return value, this query isn't sufficiently complex to set @HoursUsed, and you'll need to give us a little more detail on what you're trying to do.

Edit: This turns out to be incorrect; can't combine variable assignment with normal select. Instead, use:

SELECT COLUMN_A,dbo.fn_GetProjectHoursUsed(Project.fg_projectId)*100
    FROM SOME_TABLES

5 Comments

When I try like this it gives me this error: A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations.
In that case, you will just have to use the result directly. Treat the scalar function call no differently than a normal arithmetic expression: SELECT COLUMN_A ,100*dbo.fn_GetProjectHoursUsed(Project.fg_projectId) FROM SOME_TABLES
i try to put in a variable because if i call the function 5-6 times it will take more time the query to be executed. If I use a variable I think it will be called only once.
Maybe you can set the variable in a separate statement, then? It's hard to give better advice without having a clear picture of what you're doing.
I added the whole query to the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.