-3

C# フロントエンドで SQL Server 2008 を使用しています。C# から SQL Server に SQL 文字列を渡そうとしていますが、WHERE ステートメントに NULL 値が含まれている可能性のあるフィールドが 2 つあります。コード ビハインドのページ ロードでこのコードを取得しました (これは、データグリッドに配置されるレポート用です)。

    protected void Page_Load(object sender, EventArgs e)
    {
        SqlConnection sqlconnectionStatus = new SqlConnection(str);
        string DDL_Value = Convert.ToString(Request.QueryString["DDL_Val"]);
        string Val_Value = Convert.ToString(Request.QueryString["Val_Val"]);
        string Trk_Value = Convert.ToString(Request.QueryString["Trk_Val"]);
        string StDt_Value = Convert.ToString(Request.QueryString["StDt_Val"]);
        string EnDt_Value = Convert.ToString(Request.QueryString["EnDt_Val"]);

        string BTN_Value;
        // Because the date is stored as an INT, you have to request the string and then
        //   convert it to an INT
        string StDT_Vals = Request.QueryString["StDt_Val"].ToString();
        string EnDT_Vals = Request.QueryString["EnDt_Val"].ToString(); 
        string sqlquery;

            sqlquery = "Select DISTINCT PL.PROC_NM as Agent_Name, CCM.UNIQUE_CLAIM_ID as Unique_ID, CCM.CLAIM_ID as Claim_Number, ";
            sqlquery = sqlquery + "CCM.SOCSEC as Employee_Last_Digit, CCM.DATE_IMPORTED as Import_Date, CCM.Orig_Open_Date as Original_Review_Date, ";
            sqlquery = sqlquery + "AGL.ACCT_GRP as Account_Name, AL.ACCT_NUM as Account_Number, CCM.CDBBEN as Benefit_Option, CCM.BENEFIT_TYPE1 as Benefit_Type1, ";
            sqlquery = sqlquery + "CCM.BENEFIT_TYPE2 as Benefit_Type2, CCM.BENEFIT_TYPE3 as Benefit_Type3, CCM.Cmplt as Review_Validated, CCM.Vldtn_Cmmnts as Validation_Comments, ";
            sqlquery = sqlquery + "CCM.Gtkpr_Cmmnts as Gatekeeper_Comments, TS.StatusText as Tracking_Status ";
            sqlquery = sqlquery + "from ClosedClaims_MERGE CCM ";
            sqlquery = sqlquery + "LEFT JOIN PROC_LIST PL ON CCM.Spare = PL.LOGIN ";
            sqlquery = sqlquery + "LEFT JOIN ACCT_LIST AL ON AL.ACCT_NUM = CCM.CDBACC ";
            sqlquery = sqlquery + "LEFT JOIN ACCT_GRP_LIST AGL ON AGL.ACCT_GRP_PK = AL.ACCT_GRP_FK ";
            sqlquery = sqlquery + "LEFT JOIN TrackingStatus TS ON TS.StatusCode = CCM.TrackingStatus ";
            sqlquery = sqlquery + "WHERE CCM.Spare LIKE '" + DDL_Value + "' AND CCM.Cmplt LIKE '" + Val_Value + "' AND CCM.TrackingStatus IN (" + Trk_Value + ") AND CCM.DATE_IMPORTED >= '" + StDt_Value + "' AND CCM.DATE_IMPORTED <= '" + EnDt_Value + "'";
    }

コードは健全です。すべてのレポート パラメータに対して値が選択されていれば、問題なく動作します。問題は、CCM.Spare と CCM.Cmplt がドロップダウンから選択された特定の値を持つことも、空白のままにすることもできることです。空白のままにすると、NULL であるかどうかにかかわらず、すべての値を取得する必要があります。1 つ (または両方) を空白のままにすると、SQL が失敗します。

空白をチェックして変数を「%」に設定しようとしましたが、明らかにうまくいきません。フィールドに値があるレコードのみを取得します。

いくつかの If/Then/Else ループで詰め込む前に、可能であれば 1 つのステートメントでこれを実行したいと考えています。

これは可能ですか?

4

2 に答える 2

1

これを試してみてください。最初の基準のコードを含めました。上記で推奨されているように、パラメーターを連結しないでください。2 番目のオプションが最適な方法です。

sqlquery = sqlquery + 
    "WHERE CCM.Spare " + (DDL_Value == null ? "IS NULL" : "LIKE '" + DDL_Value + "'") + " AND ...";
sqlquery = sqlquery + 
    "WHERE CCM.Spare " + (DDL_Value == null ? "IS NULL" : "LIKE @par1") + " AND ...";


さらに、クエリの速度を上げるには、次のようにします。

sqlquery = sqlquery + 
    "WHERE " + (DDL_Value != null ? "CCM.Spare LIKE @par1 AND " : "") + "...";

CCM.Spareパラメータがnullの場合、これは基準全体を無視します。

于 2013-10-29T15:58:25.287 に答える
1

CCM.Spare と CCM.Cmplt のすべての可能な値が必要な場合は、単に述語を除外する必要があります。WHERE空のドロップダウン値を参照する句を省略した別のクエリを作成します (marc_s が指摘するように、パラメータ化されたクエリを使用することをお勧めします)。

于 2013-10-29T15:52:48.150 に答える