Как построить параметризованный запрос с ключевым словом IN sql? - PullRequest
2 голосов
/ 27 декабря 2011

Вот что я попробовал и потерпел неудачу:

      string sql = "... WHERE [personID] IN (@sqlIn) ...";
      string sqlIn = "1,2,3,4,5";
      SqlCeCommand cmd.Parameters.Add("@sqlIn", SqlDbType.NText).Value = sqlIn;

      SqlCeDataAdapter da = new SqlCeDataAdapter(cmd);
      da.Fill(ds); // > Error

Сведения об ошибке:

Типы данных ntext и image нельзя использовать в предложениях WHERE, HAVING, GROUP BY, ON или IN, кроме случаев, когда эти типы данных используются с предикатами LIKE или IS NULL.

Не могу ли я передать все идентификаторы как один параметр? Должен ли я добавить один за другим все идентификаторы?

P.S: Уведомление SqlCE

Ответы [ 2 ]

5 голосов
/ 27 декабря 2011

Вы не можете параметризовать это как один параметр. Ваш запрос выполняет "in" для single значения, поэтому по существу:

... Where personId = '1,2,3,4,5'

(дать или принять параметр). Это обычно также недопустимый или неоптимальный тест на равенство, и, конечно, это не то, что вы пытались запросить.

Опция;

  • использовать сырую конкатенацию: часто сопряжена с риском внедрения SQL и допускает повторное использование плохого плана запросов
  • на полном сервере SQL: используйте UDF для разделения одного параметра
  • на полном сервере SQL, используйте TVP
  • динамическое добавление параметров и добавление различных @ param3 и т. Д. В TSQL

Последний является наиболее надежным, и в «dapper-dot-net» есть встроенная функция, чтобы сделать это для вас (так как это обычно требуется):

int[] ids = ...
var rows = conn.Query<SomeType>(
    @"... Where Id in @ids",
    new { ids }).ToList();

Это, при запуске через dapper-dot-net, добавит параметр для каждого элемента в «идентификаторах», присвоит ему правильное значение и т. Д. И исправит SQL, чтобы он выполнялся, например:

"... Where Id in (@ids0, @ids1, @ids2)"

(если в "идентификаторах" было 3 элемента)

3 голосов
/ 27 декабря 2011

Вам нужно будет разделить строку sqlIn запятой, преобразовать каждую в целое число и вручную построить оператор IN.

  string sqlIn = "1,2,3,4,5";
  string inParams = sqlIn.Split(',');
  List<string> paramNames = new List<string>();
  for(var i = 0; i < inParams.Length; ++i){
        string paramName = "@param" + i.ToString();
        SqlCeCommand cmd.Parameters.Add(paramName, SqlDbType.Int).Value = int.Parse(inParams[i]);
        paramNames.Add(paramName);
  }

  string sql = "... WHERE [personID] IN (" +
      string.Join(",", paramNames) +
      ") ...";
...