我刚刚设法启用全文搜索,以便更轻松地搜索系统中的产品。但是,我正在使用由其他人构建的sp,并且它没有返回“Duty Call”的任何结果。事实上,我正在寻找系统中的产品“使命召唤”。如果我输入“使命召唤”,会返回结果,但删除一个单词并翻转剩余的单词不会产生结果。代码如下:
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-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
确实会返回结果。我离开了这里的联盟,并想知道你们中的一个经验丰富的程序员是否会在这里看到明显错误的东西。非常感谢你们或女士们提供的任何帮助。
非常感谢,
保
答案 0 :(得分:0)
在tf_ProductSearch
函数中WHERE子句的元素在ELSE部分中不正确地重复/关联逻辑(它与您的工作查询不匹配)。这可能是个问题。
答案 1 :(得分:0)
好的,这不是重写,因为我没有时间也没有满足您需求的要求,但这里有几个提示......
如果你不需要它,摆脱你的表值函数;将该逻辑移入存储过程。
删除IF @StoreCatItem IS NULL
语句并在WHERE子句中使用类似WHERE (@StoreCatItem IS NULL OR a.StoreItemCatID = @StoreCatItem)
的结构来合并为1个SELECT语句。如果您的目的是鼓励使用适当的索引,请在查询末尾添加OPTION(RECOMPILE)
提示,而不是复制sql。
我看到你在存储过程中正在进行分页。临时表是一个好主意,但更改其定义和插入查询只包括以正确方式排序的完整结果集的主键值加上您的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
返回记录的最终select语句应该在表变量中的键和实际数据之间进行简单的INNER JOIN;这是您选择所需的所有真实字段的地方,您不需要再次重复您的标准,因为联接将过滤您的结果。
如果您只是在学习,那么迭代创作是无可替代的。从你所知道的工作开始,并以此为基础。
享受!