0

I have just managed to enable full-text searching to make searching for products in my system easier. However, I am using an sp that was built by someone else and it is not returning any results for "Duty Call". In actual fact I am searching for "Call of Duty", a product in the system. If I type "Call of Duty" it does return a result, but removing a word and flipping the remaining words does not give results. The code is as follows:

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

The code refers to the tf_productSearch which is this:

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

This call inside a classic ASP web page with the following code:

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()

These scripts however return no results. However, typing the following code directly into the query window of the sql-server:

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

does return a result. I am out of my league here and wondered if one of you experienced programmers may see something obviously wrong here. Any help you guys or gals can provide would be greatly appreciated.

Many Thanks,

Paul

4

2 回答 2

0

函数中WHERE 子句的元素tf_ProductSearch在 ELSE 部分中重复/不正确地关联逻辑(它与您的工作查询不匹配)。这可能是问题所在。

于 2010-08-27T23:09:09.940 回答
0

好的,这不是重写,因为我没有时间也没有要求来满足您的需求,但这里有一些提示......

  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. 如果您只是在学习,迭代创建是无可替代的。从你所知道的工作开始,并以此为基础。

享受!

于 2010-08-28T01:00:41.960 回答