好的,我创建了一个存储过程,其中包括搜索特定关键字的5列。为了实现这一点,我将关键字参数拆分为函数并作为表返回。然后我使用LIKE约束在该表上执行左连接。
所以,我的工作非常漂亮,然后突然停止工作。现在它返回每一行,而不仅仅是它所需的行。
另一个警告是,如果关键字参数为空,则应忽略它。
鉴于以下内容,是否有A)明显的错误,或者B)更有效的方法来解决这个问题?
以下是我目前的情况:
ALTER PROCEDURE [dbo].[usp_getOppsPaged]
@startRowIndex int,
@maximumRows int,
@city varchar(100) = NULL,
@state char(2) = NULL,
@zip varchar(10) = NULL,
@classification varchar(15) = NULL,
@startDateMin date = NULL,
@startDateMax date = NULL,
@endDateMin date = NULL,
@endDateMax date = NULL,
@keywords varchar(400) = NULL
AS
BEGIN
SET NOCOUNT ON;
;WITH Results_CTE AS
(
SELECT opportunities.*,
organizations.*,
departments.dept_name,
departments.dept_address,
departments.dept_building_name,
departments.dept_suite_num,
departments.dept_city,
departments.dept_state,
departments.dept_zip,
departments.dept_international_address,
departments.dept_phone,
departments.dept_website,
departments.dept_gen_list,
ROW_NUMBER() OVER (ORDER BY opp_id) AS RowNum
FROM opportunities
JOIN departments ON opportunities.dept_id = departments.dept_id
JOIN organizations ON departments.org_id=organizations.org_id
LEFT JOIN Split(',',@keywords) AS kw ON
(title LIKE '%'+kw.s+'%' OR
[description] LIKE '%'+kw.s+'%' OR
tasks LIKE '%'+kw.s+'%' OR
requirements LIKE '%'+kw.s+'%' OR
comments LIKE '%'+kw.s+'%')
WHERE
(
(@city IS NOT NULL AND (city LIKE '%'+@city+'%' OR dept_city LIKE '%'+@city+'%' OR org_city LIKE '%'+@city+'%'))
OR
(@state IS NOT NULL AND ([state] = @state OR dept_state = @state OR org_state = @state))
OR
(@zip IS NOT NULL AND (zip = @zip OR dept_zip = @zip OR org_zip = @zip))
OR
(@classification IS NOT NULL AND (classification LIKE '%'+@classification+'%'))
OR
((@startDateMin IS NOT NULL AND @startDateMax IS NOT NULL) AND ([start_date] BETWEEN @startDateMin AND @startDateMax))
OR
((@endDateMin IS NOT NULL AND @endDateMax IS NOT NULL) AND ([end_date] BETWEEN @endDateMin AND @endDateMax))
OR
(
(@city IS NULL AND
@state IS NULL AND
@zip IS NULL AND
@classification IS NULL AND
@startDateMin IS NULL AND
@startDateMax IS NULL AND
@endDateMin IS NULL AND
@endDateMin IS NULL)
)
)
)
SELECT *
FROM Results_CTE
WHERE RowNum >= @startRowIndex
AND RowNum < @startRowIndex + @maximumRows;
END
答案 0 :(得分:0)
查询 -
与Predicate
一样%%
似乎非常昂贵且进程缓慢。您是否可以使用Full Text Index
?
为每个local variable
声明Input Parameter
。将相应的列名称分配给此变量。对于City,由于正在使用三列,因此为City声明三个变量并分配相应的列名称,如下所示......
Set @Local_city = 'city'
Set @Local_dept_city = 'dept_city'
最后你可以在Where clause
中使用它。这样做将排除下面的代码行。
OR
(
(@city IS NULL AND
@state IS NULL AND
@zip IS NULL AND
@classification IS NULL AND
@startDateMin IS NULL AND
@startDateMax IS NULL AND
@endDateMin IS NULL AND
@endDateMin IS NULL)
所以,我的工作非常漂亮,然后突然之间 停止工作。现在它返回每一行,而不仅仅是行 它需要。
您确定查询中使用的运算符吗?我的意思是你到处都有OR
运营商。
另一个警告是,如果关键字参数为空,则应该 忽略它。
请检查我的上述建议。
ALTER PROCEDURE [dbo].[usp_getOppsPaged]
@startRowIndex int,
@maximumRows int,
@city varchar(100) = NULL,
@state char(2) = NULL,
@zip varchar(10) = NULL,
@classification varchar(15) = NULL,
@startDateMin date = NULL,
@startDateMax date = NULL,
@endDateMin date = NULL,
@endDateMax date = NULL,
@keywords varchar(400) = NULL
AS
BEGIN
SET NOCOUNT ON;
Declare @Local_city varchar(100)
declare @Local_dept_city varchar(100)
declare @Local_org_city varchar(100)
Declare @Local_state char(2)
Declare @Local_dept_state char(2)
Declare @Local_org_state char(2)
Declare @Local_zip varchar(10)
Declare @Local_dept_zip varchar(10)
Declare @Local_org_zip varchar(10)
Declare @Local_classification varchar(15)
Declare @Local_startDateMin date
Declare @Local_startDateMax date
Declare @Local_endDateMin date
Declare @Local_endDateMin date
Declare @Local_endDateMax date
Set @Local_city = 'city'
Set @Local_dept_city = 'dept_city'
Set @Local_org_city = 'org_city'
Set @Local_state = 'state'
Set @Local_dept_state = 'dept_state'
Set @Local_org_state = 'org_state'
Set @Local_zip = 'zip'
Set @Local_dept_zip = 'dept_zip'
Set @Local_org_zip = 'org_zip'
Set @Local_classification = 'classification'
Set @Local_startDateMax = 'startDateMax'
Set @Local_endDateMin = 'endDateMin'
Set @Local_endDateMin = 'endDateMin'
Set @Local_endDateMax = 'endDateMax'
;WITH Results_CTE AS
(
SELECT opportunities.*,
organizations.*,
departments.dept_name,
departments.dept_address,
departments.dept_building_name,
departments.dept_suite_num,
departments.dept_city,
departments.dept_state,
departments.dept_zip,
departments.dept_international_address,
departments.dept_phone,
departments.dept_website,
departments.dept_gen_list,
ROW_NUMBER() OVER (ORDER BY opp_id) AS RowNum
FROM opportunities
JOIN departments ON opportunities.dept_id = departments.dept_id
JOIN organizations ON departments.org_id=organizations.org_id
LEFT JOIN Split(',',@keywords) AS kw ON
(title LIKE '%'+kw.s+'%' OR
[description] LIKE '%'+kw.s+'%' OR
tasks LIKE '%'+kw.s+'%' OR
requirements LIKE '%'+kw.s+'%' OR
comments LIKE '%'+kw.s+'%')
WHERE
(
(@city IS NOT NULL AND (city LIKE '%'+@Local_city+'%' OR dept_city LIKE '%'+@Local_dept_city+'%' OR org_city LIKE '%'+@Local_org_city+'%'))
OR
(@state IS NOT NULL AND ([state] = @Local_state OR dept_state = @Local_dept_state OR org_state = @Local_org_state))
OR
(@zip IS NOT NULL AND (zip = @Local_zip OR dept_zip = @Local_dept_zip OR org_zip = @Local_org_zip))
OR
(@classification IS NOT NULL AND (classification LIKE '%'+@Local_classification+'%'))
OR
((@startDateMin IS NOT NULL AND @Local_startDateMax IS NOT NULL) AND ([start_date] BETWEEN @Local_startDateMax AND @Local_startDateMax))
OR
((@endDateMin IS NOT NULL AND @Local_endDateMax IS NOT NULL) AND ([end_date] BETWEEN @Local_endDateMin AND @Local_endDateMax))
)
)
SELECT *
FROM Results_CTE
WHERE RowNum >= @startRowIndex
AND RowNum < @startRowIndex + @maximumRows;
END