Как заставить функцию SQL выполнить другой запрос и вернуть значение из любого запроса? - PullRequest
1 голос
/ 01 апреля 2010

Мне нужна функция, но, похоже, она не может быть понята правильно, я посмотрел примеры здесь и в других местах и ​​не могу понять, что это правильно, мне нужен дополнительный элемент, который будет включен в мой запрос, у меня есть этот запрос (который работает):

SELECT TOP 100 PERCENT SKU, Description, LEN(CONVERT(VARCHAR
(1000),Description)) AS LenDesc FROM tblItem
WHERE Title = @Title AND Manufacturer = @Manufacturer
ORDER BY LenDesc DESC

Это работает внутри функции, однако Производитель не является обязательным для этого поиска - то есть, чтобы найти описание аналогичного элемента, если его нет, другой запрос:

SELECT TOP 100 PERCENT SKU, Description, LEN(CONVERT(VARCHAR
(1000),Description)) AS LenDesc FROM tblItem
WHERE Title = @Title ORDER BY LenDesc DESC

Что пропускает производителя, как мне заставить мою функцию использовать любой запрос на основе присутствия значения производителя или нет. Причина в том, что у меня будет функция, которая сначала проверяет SKU на предмет описания, если его нет - он использует этот метод для получения описания от аналогичного продукта, а затем обновляет добавляемый продукт описанием аналогичного продукта.

Вот функция на данный момент:

ALTER FUNCTION [dbo].[GetDescriptionByTitleManufacturer]
(   
    @Title varchar(400),
    @Manufacturer varchar(160)
)
RETURNS TABLE 
AS
RETURN (
    SELECT TOP 100 PERCENT SKU, Description, LEN(CONVERT(VARCHAR
    (1000),Description)) AS LenDesc FROM tblItem
    WHERE Title = @Title AND Manufacturer = @Manufacturer
    ORDER BY LenDesc DESC
    )

Я пытался добавить BEGIN и IF ... ELSE, но каждый раз, когда я пытаюсь это сделать, я получаю ошибки или синтаксические ошибки, я хочу иметь возможность выполнять что-то вроде этой псевдофункции (которая не работает):

ALTER FUNCTION [dbo].[GetDescriptionByTitleManufacturer]
(   
    @Title varchar(400),
    @Manufacturer varchar(160)
)
RETURNS TABLE 
AS
BEGIN
IF (@Manufacturer = Null)
RETURN (
    SELECT TOP 100 PERCENT SKU, Description, LEN(CONVERT(VARCHAR
    (1000),Description)) AS LenDesc FROM tblItem
    WHERE Title = @Title ORDER BY LenDesc DESC
    )
ELSE
RETURN (
    SELECT TOP 100 PERCENT SKU, Description, LEN(CONVERT(VARCHAR
    (1000),Description)) AS LenDesc FROM tblItem
    WHERE Title = @Title AND Manufacturer = @Manufacturer
    ORDER BY LenDesc DESC
    )

END

Ответы [ 3 ]

4 голосов
/ 01 апреля 2010

Не могли бы вы сделать что-то подобное?

ALTER FUNCTION [dbo].[GetDescriptionByTitleManufacturer]
(   
    @Title varchar(400),
    @Manufacturer varchar(160)
)
RETURNS TABLE 
AS
RETURN (
    SELECT TOP 100 PERCENT SKU, Description, LEN(CONVERT(VARCHAR
    (1000),Description)) AS LenDesc FROM tblItem
    WHERE Title = @Title AND (@Manufacturer IS NULL OR Manufacturer = @Manufacturer)
    ORDER BY LenDesc DESC
    )
1 голос
/ 01 апреля 2010

Когда вы делаете AND (Manufacturer = @Manufacturer OR @Manufacturer IS NULL), вы исключаете использование индекса. У динамического поиска есть много тонких влияний на производительность, вы должны прочитать Условия динамического поиска в T-SQL. Автор Erland Sommarskog

Если у вас есть правильная версия SQL Server 2008 (SQL 2008 SP1 CU5 (10.0.2746) и более поздние версии), вы можете использовать этот маленький трюк для фактического использования индекса:

добавьте OPTION (RECOMPILE) к вашему запросу, см. Статью Эрланда , и SQL Server разрешит OR из (@Manufacturer IS NULL OR Manufacturer = @Manufacturer) перед созданием плана запроса на основе значений локальных переменных, и индекс может быть использован.

ALTER FUNCTION [dbo].[GetDescriptionByTitleManufacturer]
(   
    @Title varchar(400),
    @Manufacturer varchar(160)
)
RETURNS TABLE 
AS
RETURN
(SELECT TOP 100 
     PERCENT SKU, Description, LEN(CONVERT(VARCHAR(1000),Description)) AS LenDesc 
     FROM tblItem
         WHERE Title = @Title 
         AND (@Manufacturer IS NULL OR Manufacturer = @Manufacturer)
     ORDER BY LenDesc DESC
     OPTION (RECOMPILE) ---<<<<only valid for SQL 2008 SP1 CU5 (10.0.2746) and later
)
GO
0 голосов
/ 01 апреля 2010

Вы можете попробовать использовать NULL, если производитель не применяется:

SELECT TOP 100 PERCENT SKU, Description, LEN(CONVERT(VARCHAR
(1000),Description)) AS LenDesc FROM tblItem
WHERE Title = @Title AND (Manufacturer = @Manufacturer OR @Manufacturer IS NULL)
ORDER BY LenDesc DESC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...