存储过程不返回结果,但查询返回结果
我刚刚设法启用全文搜索,以便更轻松地在系统中搜索产品。但是,我使用的是其他人构建的 sp,它没有返回“值班呼叫”的任何结果。事实上,我正在搜索“使命召唤”,系统中的一个产品。如果我输入“使命召唤”,它确实会返回结果,但删除单词并翻转其余单词不会给出结果。代码如下:
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
确实返回结果。我不适合这里,想知道你们中的一位经验丰富的程序员是否会在这里看到一些明显的错误。如果你们能提供任何帮助,我们将不胜感激。
非常感谢,
保罗
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,这不是重写,因为我没有时间也没有要求来满足您的需求,但这里有一些提示...
如果您不需要表值函数,请删除它;将该逻辑移至存储过程中。
摆脱
IF @StoreCatItem IS NULL
语句,并在 WHERE 中使用类似WHERE (@StoreCatItem IS NULL OR a.StoreItemCatID = @StoreCatItem)
的结构子句合并为 1 个 SELECT 语句。如果您的目的是鼓励适当的索引使用,请将OPTION(RECOMPILE)
提示添加到查询末尾,而不是重复 sql。我发现您正在存储过程中进行分页。临时表是一个好主意,但更改其定义和插入查询以仅包含以正确方式排序的完整结果集的主键值以及 IDENTITY 列,但您很可能只需要一个 INT 列,而不是 BIGINT,这在临时表上并不是很重要。插入表变量的第一个查询是使用 WHERE 条件进行筛选的位置。对于您的每个标准,都可以像这样使用上面提到的构造。
WHERE(@StoreCatItem 为 NULL 或
a.StoreItemCatID = @StoreCatItem 或
a.StoreItemCatID IN (
从 StoreItemCat x 中选择 x.StoreItemCatID,其中 x.ParentID = @StoreItemCatID))
和自由文本(a.ProductName,@SearchStr)
AND a.StoreItemCatID = @StoreItemCatID
AND a.已删除 = 0
AND a.Active = 1
返回记录的最终 select 语句应该在表变量中的键和真实数据之间再次执行简单的 INNER JOIN ;您可以在此处选择所需的所有实际字段,并且无需再次重复您的条件,因为联接将过滤您的结果。
如果您只是在学习,那么迭代创建是无可替代的。从您知道有效的方法开始,并以此为基础进行构建。
享受!
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...
Get rid of your table valued function if you don't need it; move that logic into your stored procedure.
Get rid of your
IF @StoreCatItem IS NULL
statement and use a construct likeWHERE (@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 theOPTION(RECOMPILE)
hint to the end of your query instead of duplicating sql.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
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.
There is no substitute for iterative creation if you're just learning. Start with what you know works and build on it.
Enjoy!
tf_ProductSearch
函数中 WHERE 子句的元素在 ELSE 部分中重复/不正确地关联逻辑(它与您的工作查询不匹配)。这可能就是问题所在。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.