сохраненный процесс не возвращает результатов, но запрос делает - PullRequest
0 голосов
/ 28 августа 2010

Мне только что удалось включить полнотекстовый поиск, чтобы упростить поиск товаров в моей системе.Однако я использую sp, созданный кем-то другим, и он не возвращает никаких результатов для «Duty Call».На самом деле я ищу "Call of Duty", продукт в системе.Если я наберу «Call of Duty», возвращает результат, но удаление слова и переключение оставшихся слов не дает результатов.Код выглядит следующим образом:

USE [storeboard]
GO
/****** Object:  StoredProcedure [sbuser].[sp_ProductSearch]    Script Date: 08/26/2010 05:57:20 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROC [sbuser].[sp_ProductSearch]
    @StoreItemID bigint = null,
    @StoreMemberID bigint = null,
    @ProductName varchar(50) = null,
    @ProductDesc varchar(1000) = null,
    @ItemPrice float = null,
    @Active bit = null,
    @Deleted bit = null,
    @CreateDate datetime = null,
    @ShipWeight float = null,
    @TaxExempt bit = null,
    @ShipCost float = null,
    @Keywords varchar(1000) = null,
    @PG int = 1,
    @ROWCT numeric(18,2) = 1,
    @COLCT numeric(18,2) = 1,
    @MODE varchar(50),
    @StoreItemCatID bigint = null,
    @SearchStr varchar(100) = null

AS


IF @MODE = 'S1'    
    BEGIN
        SELECT
        StoreItemID,
        ProductName,
        ItemPrice,
        PG,
        MAXPG,
        TOTALRECS,
        CoverImg,
        StoreItemCatID,
        Active
        FROM sbuser.tf_ProductSearch(@PG,@ROWCT,@COLCT,@StoreItemCatID,@SearchStr)
    END

Код относится к tf_productSearch:

USE [storeboard]
GO
/****** Object:  UserDefinedFunction [sbuser].[tf_ProductSearch]    Script Date: 08/26/2010 05:46:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [sbuser].[tf_ProductSearch] (
    @PG int,
    @ROWCT numeric(18,2),
    @COLCT numeric(18,2),
    @StoreItemCatID bigint,
    @SearchStr varchar(100) = null)

RETURNS @OUT TABLE (
    StoreItemID bigint,
    ProductName varchar(50),
    ProductDesc varchar(1000),
    ItemPrice float,
    Active bit,
    CreateDate datetime,
    ShipWeight float,
    TaxExempt bit,
    ShipCost float,
    Keywords varchar(1000),
    PG int,
    MAXPG INT,
    TOTALRECS INT,
    CoverImg varchar(50),
    StoreItemCatID bigint )

AS

BEGIN

        DECLARE @START numeric(18,2);
        DECLARE @END numeric(18,2);
        DECLARE @SIZE numeric(18,2);
        DECLARE @MAXPG numeric(18,2);
        DECLARE @TOTALRECS numeric(18,2);
        DECLARE @TOTALRECS_INT int;
        DECLARE @MAXPG_INT int;
        DECLARE @TOTALRECS_REMAINDER numeric(18,2);
        SET @SIZE = @ROWCT * @COLCT
        SET @Start = (((@PG - 1) * @Size) + 1)
        SET @END = (@START + @SIZE - 1)


        DECLARE @TMP1 TABLE (
        TmpID bigint identity(1,1) primary key,
        StoreItemID bigint,
        ProductName varchar(50),
        ProductDesc varchar(1000),
        ItemPrice float,
        Active bit,
        CreateDate datetime,
        ShipWeight float,
        TaxExempt bit,
        ShipCost float,
        Keywords varchar(1000),
        CoverImg varchar(50),
        StoreItemCatID bigint )


        IF @StoreItemCatID IS NULL
            BEGIN
                INSERT INTO @TMP1 
                SELECT
                a.StoreItemID,
                a.ProductName,
                a.ProductDesc,
                a.ItemPrice,
                a.Active,
                a.CreateDate,
                a.ShipWeight,
                a.TaxExempt,
                a.ShipCost,
                a.Keywords,
                sbuser.sf_StoreItemCoverImg(a.StoreItemID) AS CoverImg,
                a.StoreItemCatID
                FROM sbuser.StoreItem a
                WHERE FREETEXT (a.ProductName, @SearchStr)
                AND Deleted = 0    
                AND Active = 1
                ORDER BY a.ProductName 
            END
        ELSE

            BEGIN
                INSERT INTO @TMP1 
                SELECT
                a.StoreItemID,
                a.ProductName,
                a.ProductDesc,
                a.ItemPrice,
                a.Active,
                a.CreateDate,
                a.ShipWeight,
                a.TaxExempt,
                a.ShipCost,
                a.Keywords,
                sbuser.sf_StoreItemCoverImg(a.StoreItemID) AS CoverImg,
                a.StoreItemCatID
                FROM sbuser.StoreItem a
                WHERE FREETEXT (a.ProductName, @SearchStr)
                AND a.StoreItemCatID = @StoreItemCatID
                AND a.Deleted = 0    
                AND a.Active = 1
                OR a.StoreItemCatID IN (SELECT StoreItemCatID FROM StoreItemCat WHERE ParentID = @StoreItemCatID)
                AND FREETEXT (a.ProductName, @SearchStr)
                AND a.Deleted = 0    
                AND a.Active = 1
                ORDER BY a.ProductName
            END



        SELECT @TOTALRECS = MAX(TMPID) FROM @TMP1
        SELECT @MAXPG = @TOTALRECS / @SIZE
        SET @TOTALRECS_REMAINDER = @TOTALRECS % @SIZE

        SET @MAXPG_INT = CAST(@MAXPG AS INT)
        SET @TOTALRECS_INT = CAST(@TOTALRECS AS INT)


        IF @TOTALRECS_REMAINDER > 0 
            BEGIN
                SET @MAXPG_INT = @MAXPG_INT + 1
            END        



        INSERT INTO @OUT
        SELECT 
            StoreItemID,
            ProductName,
            ProductDesc,
            ItemPrice,
            Active,
            CreateDate,
            ShipWeight,
            TaxExempt,
            ShipCost,
            Keywords,
            @PG,
            @MAXPG_INT,
            @TOTALRECS_INT,
            CoverImg,
            StoreItemCatID
            FROM @TMP1
            WHERE (TmpID >= @Start) AND (TmpID <= @END)        

    RETURN


END

Этот вызов внутри классической веб-страницы ASP со следующим кодом:

Dim ProductCat
Dim paryProducts
Dim ProdMaxPG
Dim pstrProductList

Const C_PRODUCTS_FE_PRODUCTROWCOUNT = 4
Const C_PRODUCTS_FE_PRODUCTCOLCOUNT = 5
SearchStr = "duty call"
StoreItemCatID = ""

cData.SQL = "sp_ProductSearch " _
          & cData.ProcFld("MODE","S1",2,True) _
          & cData.ProcFld("PG",PG,0,True) _
          & cData.ProcFld("ROWCT",C_PRODUCTS_FE_PRODUCTROWCOUNT,0,True) _
          & cData.ProcFld("COLCT",C_PRODUCTS_FE_PRODUCTCOLCOUNT,0,True) _
          & cData.ProcFld("SearchStr",SearchStr,2,True) _
          & cData.ProcFld("StoreItemCatID",StoreItemCatID,0,False)
paryProducts = cData.RSArray()

Однако эти сценарии не возвращают результатов.Однако, введя следующий код непосредственно в окно запроса sql-сервера:

USE storeboard
GO
DECLARE @SearchStr varchar(50)
SET @SearchStr = 'duty call';
SELECT
                a.StoreItemID,
                a.ProductName,
                a.ProductDesc,
                a.ItemPrice,
                a.Active,
                a.CreateDate,
                a.ShipWeight,
                a.TaxExempt,
                a.ShipCost,
                a.Keywords,
                a.StoreItemCatID
                FROM sbuser.StoreItem a
                WHERE FREETEXT (a.ProductName, @SearchStr)
                AND a.Deleted = 0    
                AND a.Active = 1
                ORDER BY a.ProductName

действительно возвращает результат.Я вышел из своей лиги здесь и подумал, может ли кто-нибудь из вас, опытных программистов, увидеть здесь что-то явно не так.Любая помощь, которую вы, ребята, можете предоставить, будет принята с благодарностью.

Большое спасибо,

Пол

Ответы [ 2 ]

0 голосов
/ 28 августа 2010

Хорошо, это не переписывание, потому что у меня нет ни времени, ни требований для удовлетворения ваших потребностей, но вот пара советов ...

  1. Избавьтесь отваша табличная функция, если она вам не нужна;переместите эту логику в свою хранимую процедуру.

  2. Избавьтесь от своего оператора IF @StoreCatItem IS NULL и используйте вместо этого конструкцию, подобную WHERE (@StoreCatItem IS NULL OR a.StoreItemCatID = @StoreCatItem), в своем предложении WHERE для объединения в 1 оператор SELECT.Если вы намеревались поощрять соответствующее использование индекса, добавьте подсказку OPTION(RECOMPILE) в конец вашего запроса вместо дублирования sql.

  3. Я вижу, что вы выполняете подкачку в своей хранимой процедуре,Временная таблица - хорошая идея, но измените ее определение и ваш запрос вставки, чтобы включить только значения первичного ключа полного набора результатов, упорядоченного в правильном порядке, плюс столбец IDENTITY, но вам, скорее всего, нужен только столбец INT, а не BIGINT,не то, чтобы это имело большое значение здесь на временном столе.Первый запрос, который вставляется в переменную таблицы, - это место, где вы фильтруете с помощью условия WHERE.Используйте упомянутую выше конструкцию так же, как и для каждого из ваших критериев.WHERE (@StoreCatItem IS NULL OR a.StoreItemCatID = @StoreCatItem OR a.StoreItemCatID IN ( SELECT x.StoreItemCatID FROM StoreItemCat x WHERE x.ParentID = @StoreItemCatID)) AND FREETEXT (a.ProductName, @SearchStr) AND a.StoreItemCatID = @StoreItemCatID AND a.Deleted = 0 AND a.Active = 1

  4. Последний оператор выбора, который возвращает ваши записи, должен выполнить простое INNER JOIN между ключами, которые есть в вашей табличной переменной, и вашими реальными данными снова;Здесь вы выбираете все нужные вам реальные поля, и вам не нужно повторять критерии снова, поскольку объединение отфильтрует ваши результаты.

  5. Ничто не заменит итеративное созданиеесли ты только учишьсяНачните с того, что, как вы знаете, работает и постройте его.

Наслаждайтесь!

0 голосов
/ 28 августа 2010

Элементы вашего предложения WHERE в вашей функции tf_ProductSearch повторяются / неправильно связывают логику в части ELSE (она не соответствует вашему рабочему запросу). Это может быть проблемой.

...