Веб-API, использующий параметры команды, не возвращает никаких данных

Веб-API для запроса базы данных Oracle, которая получает массив строк в качестве входного параметра. Я пытаюсь использовать параметры команды, чтобы избежать инъекции 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;
                }
            }

        }
    }
}

Ниже показано, что я получаю при отладке в commandText selectCommand.

"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, я получаю записи. любая помощь приветствуется.


person user4912134    schedule 04.08.2016    source источник
comment
какой у вас параметр id? как выглядит сгенерированный sql-запрос перед его выполнением?   -  person shirbr510    schedule 04.08.2016
comment
ID — это строка, которую мы даем при вызове API. Сгенерированный запрос должен выглядеть примерно так: Select * from STCD, где STDREF IN('a001','a002'), если мы вызываем API как http://local host:80/API/ PData?id='a001'&I'd='a002'   -  person user4912134    schedule 04.08.2016
comment
Я знаю. Я прошу пример вашего запроса GET. например: http://example.com/api/somecontroller/getdetails?id=1&id=2&id=3& id=4   -  person shirbr510    schedule 04.08.2016
comment
Да, это будет просто 'localhost/api/PData?id='a001'&id ='a002' 'это мой открытый класс контроллера API PDataController : ApiController   -  person user4912134    schedule 04.08.2016
comment
и я предполагаю, что вы пытались получить вывод из вашего StringBuilder и проверили значение в клиенте Oracle? может быть, проблема с форматированием вашего SQL или добавлением строки?   -  person shirbr510    schedule 04.08.2016
comment
Это должно быть strQuery = strQuery + sb.ToString() + ); Просто опечатка?   -  person Steve    schedule 04.08.2016
comment
@steve Нет, Стив, я удалил strQuery, потому что strQuery содержит весь оператор запроса, и даже sb снова имеет весь запрос, поэтому я удалил его. Если я запускаю с strQuery = strQuery + sb.ToString() +); это дает мне ошибку, например, отсутствие круглых скобок в операторе adapter.Fill(selectResults)   -  person user4912134    schedule 04.08.2016
comment
Затем вам нужно использовать отладчик, чтобы увидеть, что именно представляет собой текст запроса, отправленный в адаптер. Заполните и проверьте, соответствует ли список параметров заполнителям параметров. Кстати, ваше упоминание о SQLite сбивает с толку. Мы говорим об Oracle, верно?   -  person Steve    schedule 04.08.2016
comment
Это была опечатка, которую я пробовал в SQL Developer, и она возвращает результат   -  person user4912134    schedule 04.08.2016
comment
Отсутствие IN( в исходном тексте запроса   -  person Steve    schedule 04.08.2016
comment
Давайте продолжим обсуждение в чате.   -  person user4912134    schedule 04.08.2016
comment
@Steve, набор данных пуст. Я добавил его изображение. Но с тем же идентификатором, который я пробовал отлаживать, я получаю результаты от SQLDeveloper.   -  person user4912134    schedule 04.08.2016


Ответы (1)


Из чата с ОП выяснилось, что ОП добавил одинарные кавычки вокруг идентификатора параметра массива. Значения, полученные из строки запроса, отформатированной таким образом

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

и это была попытка передать строку в качестве значения параметра.

Однако если вы используете параметр и указываете его тип данных (NVarChar2), то механизм базы данных знает о значении достаточно, чтобы самостоятельно правильно заключать в кавычки, поэтому значения параметров не должны заключаться в одинарные кавычки.

Изменение формата строки запроса на

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

исправил проблему

person Steve    schedule 04.08.2016