2016-12-27 11 views
0

column_nameおよび値の代わりにwhere句に2つのパラメータを追加しようとしています。私がオンラインで見てきたすべてのものは、ストアドプロシージャにすでにある列の値のパラメータの例を示していますが、列自体のためのパラメータの例はありません。ここでストアド・プロシージャのSQL where句column_nameにパラメータを追加します

は、私がこれまで持っているものです。

CREATE PROCEDURE [mobile].[p_get_insptn_log_by_date] 
    (@SEARCHBY SYSNAME, @SEARCHVALUE NVARCHAR(100)) 
AS 
    SET NOCOUNT ON 

    SELECT 
     [id], [application_name], [login_id], [log_ts], 
     [insptn_log_msg_type_code], [log_msg_text], [insptn_log_lvl_code] 
    FROM 
     [dbo].[Insptn_log] 
    WHERE 
     insptn_log_lvl_code <> 'info' AND 
     CASE 
      WHEN @SEARCHBY = 'application_name' 
       THEN application_name = @SEARCHVALUE 
      WHEN @SEARCHBY = 'login_id' 
       THEN login_id = @SEARCHVALUE 
      WHEN @SEARCHBY = 'log_ts' log_ts < CONVERT(DATETIME, @SEARCHVALUE) 
     END 

ことがあるので、SQL Server Management Studioのは、case文の最初の=符号と第二WHEN下が構文エラーをというエラーがスローされますCASE声明。

このタスクを実行するための正しい構文を探しています。どんな助けでも大歓迎です。

+++++ EDIT +++++

私は、以前@SEARCHVALUEのタイプは、ユーザーが@SEARCHBY値として「log_ts」を選択したときDATETIMENVARCHARから行くことができることになりますことを言及しませんでした。私はまた、私のMVCアプリケーションから来るParamsのDataTypesのための上記のスクリプトを更新しました。

+1

@SEARCHBYはCHAR(1文字以上)にすることはできません。 – DVT

答えて

2

これを行うにははるかに効率的で洗練された方法のようなものになるだろう......

CREATE PROC [mobile].[p_get_insptn_log_by_date] 
    @SEARCHBY SYSNAME   = NULL --<-- Use appropriate data type 
    , @SEARCHVALUE NVARCHAR(1000) = NULL --<-- Use appropriate data length 
AS 
BEGIN 
    SET NOCOUNT ON; 
Declare @Sql NVARCHAR(MAX); 

SET @Sql = N'SELECT [id] 
        ,[application_name] 
        ,[login_id] 
        ,[log_ts] 
        ,[insptn_log_msg_type_code] 
        ,[log_msg_text] 
        ,[insptn_log_lvl_code] 
      FROM [dbo].[Insptn_log] 
      WHERE insptn_log_lvl_code <> ''info''' 
      + CASE WHEN @SEARCHBY IS NOT NULL AND @SEARCHVALUE IS NOT NULL 
       THEN N' AND ' + QUOTENAME(@SEARCHBY) + N' = @SEARCHVALUE' ELSE N'' END 

Exec sp_executesql @Sql 
        ,N'@SEARCHVALUE NVARCHAR(1000)' 
        ,@SEARCHVALUE 
END 

sp_executesqlを使用すると、パラメタ同じストアドプロシージャの実行計画を蝕みました。そうでなければ、where句にこれらのcase statementを指定すると、特定のパラメータセットには最適かもしれませんが、他のパラメータセットにはあまり適していない1つの実行プランで終わることがあります。

また、常にvarchar/char/nchar/nvarchar変数の長さを定義する必要があります。それ以外の場合は、SQLサーバーのデフォルト値である1に設定されます。キャスト/変換機能では、デフォルト値は30ですが、具体的には正しい長さを使用することをお勧めします。

+0

したがって、SEARCHBYパラメータは、作成中のアプリケーションでユーザーが選択する列の名前で、文字列として使用されます。私はまだパラメータにSYSNAME型を使用したいですか? – tCoe

+2

@tCoe 'SYSNAME'は、SQL Serverオブジェクト名(テーブル、カラム、ビューなど)を格納するために作成されたデータ型です。はい、これはあなたのケースでは '@ SEARCHBY'変数のための最良のデータ型になります。 –

+0

アプリケーション側を一掃したら、これは完全に機能しました。ありがとうございました。 – tCoe

0

まだ、私はこの状況を処理するための良い方法であるべきだと思う。この

良い
CREATE PROC [mobile].[p_get_insptn_log_by_date](@SEARCHBY VARCHAR(100), @SEARCHVALUE NVARCHAR) 

AS 
SET NOCOUNT ON 
SELECT [id] 
,[application_name] 
,[login_id] 
,[log_ts] 
,[insptn_log_msg_type_code] 
,[log_msg_text] 
, [insptn_log_lvl_code] 
FROM [dbo].[Insptn_log] 
WHERE insptn_log_lvl_code <> 'info' and 
((@SEARCHBY = 'application_name' AND application_name = @SEARCHVALUE) 
OR (@SEARCHBY = 'login_id' AND login_id = @SEARCHVALUE) 
OR (@SEARCHBY = 'log_ts' AND log_ts < @SEARCHVALUE) 
) 

をお試しください:

CREATE PROC [mobile].[p_get_insptn_log_by_date](@SEARCHBY VARCHAR(100), @SEARCHVALUE NVARCHAR) 

AS 
SET NOCOUNT ON 

IF (@SEARCHBY = 'application_name') 
    BEGIN 
    SELECT [id] 
    ,[application_name] 
    ,[login_id] 
    ,[log_ts] 
    ,[insptn_log_msg_type_code] 
    ,[log_msg_text] 
    , [insptn_log_lvl_code] 
    FROM [dbo].[Insptn_log] 
    WHERE insptn_log_lvl_code <> 'info' and application_name = @SEARCHVALUE 
    END 
ELSE IF (@SEARCHBY = 'login_id') 
    BEGIN 
    SELECT [id] 
    ,[application_name] 
    ,[login_id] 
    ,[log_ts] 
    ,[insptn_log_msg_type_code] 
    ,[log_msg_text] 
    , [insptn_log_lvl_code] 
    FROM [dbo].[Insptn_log] 
    WHERE insptn_log_lvl_code <> 'info' and login_id = @SEARCHVALUE 
    END 
ELSE IF (@SEARCHBY = 'log_ts') 
    BEGIN 
    SELECT [id] 
    ,[application_name] 
    ,[login_id] 
    ,[log_ts] 
    ,[insptn_log_msg_type_code] 
    ,[log_msg_text] 
    , [insptn_log_lvl_code] 
    FROM [dbo].[Insptn_log] 
    WHERE insptn_log_lvl_code <> 'info' and log_ts < @SEARCHVALUE 
    END; 
+0

あなたの提案された解決策には、重大なパフォーマンス上の問題があります。S –

+0

@ M.Ali詳細を教えてください。 – DVT

+0

テーブルを作成し、約100万行を追加し、同様のストアドプロシージャを作成し、異なる値を渡してプロシージャを実行する方法を確認し、sp_recompileコマンドを使用して、実行前に実行プランを再コンパイルし、あなたは以前に渡しましたが、それを再コンパイルする必要はありません。 –

関連する問題