【发布时间】:2015-09-10 10:50:40
【问题描述】:
我有一个 MS SQL 2005 存储过程,我将一个 ID 从网页传递给它。
ID 用于将预先设置的搜索条件从小部件类别登录页面的数据库中读取到一组变量中。
然后在 SELECT 中使用这些变量来搜索小部件项目的数据库。访问者的页面选择可以覆盖某些变量,例如最高价格。
我想检查 SELECT 是否返回记录,如果没有,则默认为着陆页的正常标准,以确保访问者总是看到一些项目。
我曾尝试使用@@ROWCOUNT 来检查第一个 SELECT,但是由于 SELECT 相当复杂(我在下面的示例中删除了很多字段),因此运行它两次的性能损失是不可接受的。第一个 SELECT 本身需要大约 1 秒,而检查 @@ROWCOUNT = 0 并再次运行 SELECT 大约需要 4 秒。
如果第一个 SELECT 没有返回任何记录,是否有更好的方法来完成此检查和返回记录?
我还想在存储过程结束时只返回一个记录集,而不是两个。
对此进行研究后,我发现有人在两次选择中使用 UNION ALL,但我认为在这种情况下它对我没有帮助。我还想通过一个内容为 True 或 False 的字段来了解使用了哪个 SELECT,这样我就可以在网站上标记是否没有找到记录。
感谢您的帮助。
CREATE PROCEDURE dbo.NW_LANDING_GET_Widgets
/* options from the web page */
@WidgetID int,
@PageNumber int,
@WidgetsPerPage int,
@Sort VARCHAR(1),
@MinPrice int,
@MaxPrice int,
@Override_WidgetType varchar(20),
@Override_WidgetInfo1 int
AS
SET NOCOUNT ON
BEGIN
/* ---------- Declare variables for criteria to be gathered from WidgetLanding table ------------ */
DECLARE @WidgetCategory1 varchar(50)
DECLARE @WidgetCategory2 varchar(50)
DECLARE @WidgetType varchar(30)
DECLARE @WidgetInfo1 int
/* ---------- Read default criteria into variables from WidgetLanding table ----- */
SELECT
@WidgetCategory1=Criteria_WidgetCategory1,
@WidgetCategory2=Criteria_WidgetCategory2,
@WidgetType=Criteria_WidgetType
FROM dbo.WidgetLanding
WHERE pk_WidgetID = @WidgetID
/* -------- Set PageNumber variable for SELECT of Widgets ----------- */
SET @PageNumber=(@PageNumber-1)*@WidgetsPerPage
/* Set Minimum and Maximum Prices - if Null, set highest and lowest number possible */
DECLARE @Min int
DECLARE @Max int
SET @Min = ISNULL(@MinPrice,0)
SET @Max = ISNULL(@MaxPrice,999999999)
/* -------- Override variables if visitor has changed the search criteria from default ------------------- */
IF @Override_WidgetType is not null
BEGIN
SET @WidgetType=@Override_WidgetType
END
IF @Override_WidgetInfo1 is not null
BEGIN
SET @WidgetInfo1=@Override_WidgetInfo1
END
/* ------------------- Retrieve widget records based on variables ------ */
SELECT TOP(@WidgetsPerPage) * FROM (SELECT RowID=ROW_NUMBER()
OVER (ORDER BY
CASE WHEN dbo.Widgets.Featured_WidgetLandingID = @WidgetID then 1 else 0 end DESC,
CASE WHEN @Sort = 'D' THEN dbo.Widgets.Price END DESC, /* Price Descending */
CASE WHEN @Sort = 'U' THEN dbo.Widgets.Price END ASC, /* Price Ascending */
CASE WHEN @Sort = 'P' THEN dbo.Widgets.viewed END DESC, /* Popular */
CASE WHEN @Sort = 'L' THEN dbo.Widgets.Date END DESC), /* Latest */
Count(dbo.Widgets.WidgetID) OVER() As TotalRecords,
dbo.Widgets.Price,
dbo.Widgets.WidgetID,
dbo.Widgets.WidgetCategory1,
dbo.Widgets.WidgetCategory2,
dbo.Widgets.WidgetType,
dbo.Widgets.WidgetType2,
dbo.Widgets.WidgetInfo1
FROM dbo.Widgets
WHERE
(WidgetCategory1 = @WidgetCategory1 OR @WidgetCategory1 is null) AND
(WidgetCategory2 = @WidgetCategory2 OR @WidgetCategory2 is null) AND
(Price >= @Min AND Price <= @Max) AND
(WidgetInfo1 >= @WidgetInfo1 OR @WidgetInfo1 is null)
) TAB WHERE TAB.RowId > CAST(@PageNumber AS INT)
/*
-----------------------------
THIS IS WHERE I WANT TO CHECK IF RECORDS ARE RETURNED - IF NOT DO ANOTHER SELECT BUT WITHOUT OVERRIDING VARIABLES SO RECORDS WILL ALWAYS BE RETURNED
-----------------------------
*/
END
SET NOCOUNT OFF
【问题讨论】:
-
如果您进行计数(),查询会运行得更快吗?换句话说,声明一个recordcount变量,设置recordcount = count() ...
-
恐怕我不是 SQL 专家。你能解释一下我应该把这个放在哪里吗?非常感谢。
标签: sql sql-server stored-procedures rowcount