0

わかりました。とりわけ、特定のキーワードを 5 つの列で検索するストアド プロシージャを作成しました。これを実現するために、関数によって分割され、テーブルとして返されるキーワード パラメーターを用意しました。次に、LIKE 制約を使用して、そのテーブルで左結合を実行します。

それで、私はこれがうまく機能していましたが、突然機能しなくなりました。必要な行だけではなく、すべての行が返されるようになりました。

もう 1 つの注意点は、キーワード パラメータが空の場合は無視する必要があるということです。

以下の内容を考えると、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 の場合、3 つの列が使用されているため、City の 3 つの変数を宣言し、対応する列名を割り当てます。以下のように...

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オペレーターがいます。

もう 1 つの注意点は、キーワード パラメータが空の場合は無視する必要があるということです。

上記の提案を確認してください。

最終クエリ

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 に答える