0

好的,我创建了一个存储过程,除其他外,它正在为特定关键字搜索 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
4

1 回答 1

0

查询-

  1. 你能告诉我们以前工作的版本吗?
  2. 您是否使用任何源代码控制来跟踪所做的更改?

我的建议

就像看起来非常昂贵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
于 2012-07-03T14:52:55.360 回答