views:

74

answers:

2

Hi all,

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

A: 

The elements of your WHERE clause within your tf_ProductSearch function are repeated / associating the logic improperly in the ELSE portion (it doesn't match your working query). That may be the issue.

Tahbaza
OK, so how would you rewrite this, as this is all very new to me.. Please help me resolve this..
neojakey
Rewriting is a different story (for instance, I don't know why you have a table-valued function at all but I'm also not familiar with your requirements...) To get what you have working debug it by testing your tf_ProductSearch function by itself. Take your working query and put it in your function, temporarily commenting out /* */ the queries that do not work. When that works start comparing the differences and adding back what you need. Good luck!
Tahbaza
I hear ya, although I have like 2 weeks experience with t-sql. I would really appreciate seeing how you would write this. Please show me, I am desperate here!
neojakey
A: 

Ok, this isn't a rewrite because I don't have time nor the requirements to meet your needs but here are a couple of tips...

  1. Get rid of your table valued function if you don't need it; move that logic into your stored procedure.

  2. Get rid of your IF @StoreCatItem IS NULL statement and use a construct like WHERE (@StoreCatItem IS NULL OR a.StoreItemCatID = @StoreCatItem) instead in your WHERE clause to consolidate into 1 SELECT statement. If your intent was to encourage appropriate index usage add the OPTION(RECOMPILE) hint to the end of your query instead of duplicating sql.

  3. I see that you're doing paging in your stored procedure. The temp table is a good idea but change its definition and your insert query to only include the primary key values of the full resultset ordered in the correct fashion plus your IDENTITY column, but you very likely just need an INT column there, not BIGINT, not that it matters much here on a temp table. The first query that inserts into your table variable is where you filter with your WHERE condition. Use the construct mentioned above like so for each of your criteria. 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. The final select statement that returns your records should do a simple INNER JOIN between the keys you have in your table variable and your real data again; this is where you select all of the real fields you want and you don't need to repeat your criteria again since the join will filter your results.

  5. There is no substitute for iterative creation if you're just learning. Start with what you know works and build on it.

Enjoy!

Tahbaza
With your amazing advice I resolved the issue. Many Thanks Tahbaza
neojakey