Присвойте значение переменной в операторе SELECT - PullRequest
2 голосов
/ 22 июля 2011

У меня есть запрос 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 ]

2 голосов
/ 22 июля 2011

Вы можете использовать подобъект, подобный этому:

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

Переменная не требуется.

2 голосов
/ 22 июля 2011

Я частично угадываю вашу схему, но, может быть, использование временной таблицы поможет?например, что-то вроде:

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 голос
/ 22 июля 2011

Попробуйте, это будет использовать функцию только один раз для каждой строки, и вы можете обратиться к результату функции

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 
0 голосов
/ 22 июля 2011

Когда вы устанавливаете переменную в предложении 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
0 голосов
/ 22 июля 2011

Это сработало для меня:

    DECLARE @HoursUsed float

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

Попробуйте удалить внешние паран.

0 голосов
/ 22 июля 2011

Попробуйте это:

SELECT @HoursUsed = dbo.fn_GetProjectHoursUsed(Project.fg_projectId)
...and rest of your query
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...