在SELECT语句中为变量赋值

时间:2011-07-21 23:20:00

标签: tsql sql-server-2008

我有这个SQL Server查询:

DECLARE @HoursUsed float

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

我需要将函数的结果添加到变量中,因为我将在稍后的查询中需要它。

数据库功能本身工作正常。如果我从SELECT中删除变量,它就可以正常工作。

如果我尝试像这样运行查询,则会抛出如下错误:

  

语法不正确=,),as。

整个查询多次使用此函数,我遇到了性能问题。所以这就是为什么我想把值放在变量中并只调用一次函数。

感谢您的帮助

编辑: 这是完整的查询。

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'

6 个答案:

答案 0 :(得分:2)

我部分猜测你的架构,但也许使用临时表会有帮助吗? 例如类似的东西:

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

另请注意,在某些上下文中使用标量值UDF会导致性能问题(我猜你的UDF会返回一个标量?) - 如果可能的话,最好使用内联表值UDF。

答案 1 :(得分:2)

你可以使用这样的子选择:

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

无需变量。

答案 2 :(得分:1)

试试这个,它只会为每一行使用一次函数,你可以参考函数结果

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 

答案 3 :(得分:0)

试试这个:

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

答案 4 :(得分:0)

这对我有用:

    DECLARE @HoursUsed float

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

尝试移除外部的背景。

答案 5 :(得分:0)

在SELECT子句中设置变量时,该变量不需要自己的SELECT关键字。正确的形式应该是:

DECLARE @HoursUsed float

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

如果fn_GetProjectHoursUsed()具有表返回值,则此查询不足以设置@HoursUsed,并且您需要向我们提供有关您尝试执行的操作的更多详细信息。

编辑:结果证明这是不正确的;无法将变量赋值与正常选择相结合。相反,使用:

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