1

入力パラメーターとして文字列の配列を受け取る Oracle データベースにクエリを実行する Web API。コマンド パラメーターを使用して SqL インジェクションを回避しようとしていますが、以下のコードではエラーはスローされませんが、結果は得られません。

public class PDataController : ApiController
{
    public HttpResponseMessage Getdetails([FromUri] string[] id)
    {

        List<OracleParameter> prms = new List<OracleParameter>();
        string connStr = ConfigurationManager.ConnectionStrings["PDataConn"].ConnectionString;
        using (OracleConnection dbconn = new OracleConnection(connStr))
        {
            var inconditions = id.Distinct().ToArray();
            var srtcon = string.Join(",", inconditions);
            DataSet userDataset = new Dataset();
            var strQuer = @"SELECT STCD_PRIO_CATEGORY_DESCR.DESCR AS CATEGORY,  
            STCD_PRIO_CATEGORY_DESCR.SESSION_NUM AS SESSION_NUMBER,  
            Trunc(STCD_PRIO_CATEGORY_DESCR.START_DATE) AS SESSION_START_DATE, 
            STCD_PRIO_CATEGORY_DESCR.START_DATE AS SESSION_START_TIME  
            FROM STCD_PRIO_CATEGORY_DESCR 
            WHERE STCD_PRIO_CATEGORY_DESCR.STD_REF(";
            StringBuilder sb = new StringBuilder(strQuery);
            for(int x = 0; x < inconditions.Length; x++)
            {
                sb.Append(":p" + x + ",");
                OracleParameter p = new OracleParameter(":p" + x,OracleDbType.NVarchar2 );
                p.Value = inconditions[x];
                prms.Add(p);
            }
            if(sb.Length > 0) sb.Length--;
            strQuery = strQuery + sb.ToString() + ")";
            using (OracleCommand selectCommand = new OracleCommand(strQuery, dbconn))
            {
                 selectCommand.Parameters.AddRange(prms.ToArray());
                 using (OracleDataAdapter adapter = new OracleDataAdapter(selectCommand))
                {
                    DataTable selectResults = new DataTable();
                    adapter.Fill(selectResults);
                    var returnObject = new { data = selectResults };
                    var response = Request.CreateResponse(HttpStatusCode.OK, returnObject, MediaTypeHeaderValue.Parse("application/json"));
                    ContentDispositionHeaderValue contentDisposition = null;
                    if (ContentDispositionHeaderValue.TryParse("inline; filename=ProvantisStudyData.json", out contentDisposition))
                    {
                        response.Content.Headers.ContentDisposition = contentDisposition;
                    }
                    return response;
                }
            }

        }
    }
}

以下は、selectCommandのcommandTextでデバッグ中に取得しているものです

"SELECT \r\n STCD_PRIO_CATEGORY_DESCR.DESCR AS CATEGORY, \r\n 
 STCD_PRIO_CATEGORY_DESCR.SESSION_NUM AS SESSION_NUMBER, \r\n 
 Trunc(STCD_PRIO_CATEGORY_DESCR.START_DATE) AS SESSION_START_DATE, \r\n  
 STCD_PRIO_CATEGORY_DESCR.START_DATE AS SESSION_START_TIME  \r\n  
 FROM \r\n 
 STCD_PRIO_CATEGORY_DESCR \r\n 
 WHERE \r\n 
 STCD_PRIO_CATEGORY_DESCR.STD_REF IN(SELECT \r\n 
 STCD_PRIO_CATEGORY_DESCR.DESCR AS CATEGORY, \r\n 
 STCD_PRIO_CATEGORY_DESCR.SESSION_NUM AS SESSION_NUMBER, \r\n 
 Trunc(STCD_PRIO_CATEGORY_DESCR.START_DATE) AS SESSION_START_DATE, \r\n  
 STCD_PRIO_CATEGORY_DESCR.START_DATE AS SESSION_START_TIME  \r\n  
 FROM \r\n 
 STCD_PRIO_CATEGORY_DESCR \r\n 
 WHERE \r\n 
 STCD_PRIO_CATEGORY_DESCR.STD_REF IN(:p0)"

今あげてるから

strQuery = strQuery+ sb.ToString() + ")";

選択を繰り返しています。でも与えるだけなら

 strQuery = sb.ToString() + ")";

一方、デバッグ中の strQuery は

SELECT \r\n STCD_PRIO_CATEGORY_DESCR.DESCR AS CATEGORY, \r\n 
STCD_PRIO_CATEGORY_DESCR.SESSION_NUM AS SESSION_NUMBER, \r\n 
Trunc(STCD_PRIO_CATEGORY_DESCR.START_DATE) AS SESSION_START_DATE, \r\n  
STCD_PRIO_CATEGORY_DESCR.START_DATE AS SESSION_START_TIME  \r\n  
FROM \r\n 
STCD_PRIO_CATEGORY_DESCR \r\n 
WHERE \r\n 
STCD_PRIO_CATEGORY_DESCR.STD_REF IN(:p0)

ここに画像の説明を入力

私がお返しするのは、

{"data":[]}

受け取る入力は文字列の配列であるため、p0 を '' で囲む必要があります。

しかし、SQL開発者で試したときと同じIDでレコードを取得しています。どんな助けでも大歓迎です。

4

1 に答える 1

1

OP とのチャットから、OP が配列パラメーター ID を一重引用符で囲んでいることがわかりました。この方法でフォーマットされたクエリ文字列から受け取った値

http:// localhost:80/api/PData?id='JW217T_01'

これは、パラメーター値として文字列を渡そうとしたものです。

ただし、パラメーターを使用してそのデータ型 (NVarChar2) を指定すると、データベース エンジンは値について十分に認識しており、それ自体で正しい引用を行うことができるため、パラメーターの値を一重引用符で囲む必要はありません。

クエリ文字列の形式を次のように変更します

http:// localhost:80/api/PData?id=JW217T_01

問題を修正しました

于 2016-08-04T12:42:48.840 に答える