Как делание like в PostgreSQL перемещая его параметры

Я работаю с C# и PostgreSQL Восток - консультация, которая у меня есть, но меня не приносит ничто.

public static IEnumerable<Articulo> SelectList(UniversalExtend filter)
    {
        using (var cn = new NpgsqlConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
        {
            cn.Open();
            using (var cmd = cn.CreateCommand())
            {
                cmd.CommandText = @"SELECT IdArticulo, Descripcion FROM tblarticulos
                 WHERE (IdArticulo IS NULL OR IdArticulo LIKE @IdArticulo)
                 AND (Descripcion IS NULL OR Descripcion LIKE @Descripcion)";

                //cmd.CommandText = @"SELECT idArticulo, descripcion FROM tblarticulos
                //WHERE ((IdArticulo IS NULL) OR (idarticulo LIKE '%' || @idarticulo || '%'))
                //AND ((Descripcion IS NULL) OR (descripcion LIKE '%' || @descripcion || '%'))";


                cmd.Parameters.AddWithValue("@idarticulo", string.IsNullOrEmpty(filter.Id)
                    ? (object)DBNull.Value
                    : $"%{filter.Id}%");
                cmd.Parameters.AddWithValue("@descripcion", string.IsNullOrEmpty(filter.Descripcion)
                    ? (object)DBNull.Value
                    : $"%{filter.Descripcion}%");

                //cmd.Parameters.AddWithValue("@idarticulo", string.IsNullOrEmpty(filter.Id)
                //    ? (object)DBNull.Value
                //    : filter.Id);
                //cmd.Parameters.AddWithValue("@descripcion", string.IsNullOrEmpty(filter.Descripcion)
                //    ? (object)DBNull.Value
                //    : filter.Descripcion);

                var _articulo = new List<Articulo>();   
                using (NpgsqlDataReader reader = cmd.ExecuteReader())
                {
                    while(reader.Read())    
                    {
                        var a = new Articulo()
                        {
                            IdArticulo = Convert.ToString(reader["idarticulo"]),
                            Descripcion = Convert.ToString(reader["descripcion"])
                        };
                        _articulo.Add(a);
                    }
                }
                return _articulo.ToList();   
            }
3
задан 09.01.2017, 22:44
0 ответов

Консультация должна бы быть (без %):

cmd.CommandText = @"SELECT IdArticulo, Descripcion FROM tblarticulos
                WHERE ((IdArticulo IS NULL) OR (IdArticulo LIKE @IdArticulo))
                AND ((Descripcion IS NULL) OR (Descripcion LIKE @Descripcion))";

И потом, когда ты перемещаешь его параметры в объект command, там ты добавляешь его % в цепь, которую ты распределяешь ему в каждый параметр:

  • @IdArticulo => $"%{idArticulo}%"
  • @Descripcion => $"%{descripcion}%"

Редактирование

он дает мне эту ошибку: Parameter '@IdArticulo' must have its value set

Это проистекает того, что ты не используешь условие string.IsNullOrEmpty() правильно. Благодаря тому, что ты проверяешь, если цепь вместе с % будь пустой или null, очевидно, никогда он не возвратит тебя true, потому что он всегда будет иметь "%%" как минимум. Это следует, в котором даже если стоимость да - в null, в любом случае код заканчивает тем, что останавливается в else, то, что дает тебе ошибку.

Исправленная версия:

cmd.Parameters.AddWithValue(
    "@IdArticulo",
    string.IsNullOrEmpty(filter.Id)
        ? (object)DBNull.Value
        : $"%{filter.Id}%");

cmd.Parameters.AddWithValue(
    "@Descripcion",
    string.IsNullOrEmpty(filter.Descripcion)
        ? (object)DBNull.Value
        : $"%{filter.Descripcion}%");

Нужно упоминать о том, что ответ @Angeldev также был бы должен функционировать правильно. Хотя мне кажется немного странным, что в неких случаях условие консультацией заканчивается в IdArticulo LIKE '%' || null || '%'. Но он верно действительный для твоей ситуации.

Редактирование 2

Кроме проблемы с LIKE, у консультации есть другой problemita. Согласно твоим комментариям, намерение состоит в том, чтобы только были сделаны поиски с IdArticulo и Descripcion если стоимость для этих параметров он не в null. Но это не то, что консультация делает, потому что условия IdArticulo IS NULL и Descripcion IS NULL они делаются с полями в базе данных, когда в действительности твое намерение состоит в том, чтобы проверять, - ли параметры в null.

Правильная консультация, согласно которому поиски она должна быть этой (он ощущается, что я добавил его @ напротив в условия @xxx IS NULL, и я воспользовался возможностью, чтобы снимать скобку ненужные):

cmd.CommandText = @"SELECT IdArticulo, Descripcion FROM tblarticulos
                     WHERE (@IdArticulo IS NULL OR IdArticulo LIKE @IdArticulo)
                AND (@Descripcion IS NULL OR Descripcion LIKE @Descripcion)";

Редактирование 3

И если тебе нужно, чтобы сравнение проигнорировало различия прописных букв и строчных букв, в PostgreSQL ты можешь использовать оператор ILIKE вместо LIKE:

cmd.CommandText = @"SELECT IdArticulo, Descripcion FROM tblarticulos
                     WHERE (@IdArticulo IS NULL OR IdArticulo ILIKE @IdArticulo)
                AND (@Descripcion IS NULL OR Descripcion ILIKE @Descripcion)";

Редактирование 4

Ok, я думаю, что это хорошая.

Проблема с моим редактированием 2 из него добавлять @ напротив условия @idArticulo IS NULL, хотя идея правильна, он состоит в том, что сейчас драйвер стоит ему в том, чтобы определять тип параметра, когда стоимость параметра - null. Действительно, тяжелый определять тип выражения NULL IS NULL.

could not определил дату type of parameter 1$

Чтобы это решать, ты должен изменять решение cmd.Parameters.AddWithValue чтобы определять тип ясно. В любом случае, даже, если бы проблема не произошла, всегда это хорошая мысль определять тип ясно по причинам, о которых я не буду упоминать здесь, чтобы не вытекать из темы.

Так что сочетая все это перед выражением, код остался бы таким:

// Usando ILIKE para evitar el problema de las diferencias 
// de mayúscuas y minúsculas
cmd.CommandText = @"SELECT IdArticulo, Descripcion FROM tblarticulos
             WHERE (@IdArticulo IS NULL OR IdArticulo ILIKE @IdArticulo)
             AND (@Descripcion IS NULL OR Descripcion ILIKE @Descripcion)";

cmd.Parameters.AddWithValue(
    "@IdArticulo",
    NpgsqlDbType.Varchar, // le agregué esto aquí
    string.IsNullOrEmpty(filter.Id)
        ? (object)DBNull.Value
        : $"%{filter.Id}%");

cmd.Parameters.AddWithValue(
    "@Descripcion",
    NpgsqlDbType.Varchar, // le agregué esto aquí
    string.IsNullOrEmpty(filter.Descripcion)
        ? (object)DBNull.Value
        : $"%{filter.Descripcion}%");
3
ответ дан 03.12.2019, 17:48
  • 1
    он дает мне эту ошибку Параметер ' @IdArticulo' must have its оцените set, измените вопрос завершая весь query –  09.01.2017, 19:05
  • 2
    Ошибка tení которого видеть с string.IsNullOrEmpty(), хороший, что agregastes в вопрос. Заметь отдельно, не я habí в произошедший, но то, что он говорит @Angeldev, правильно tambié n, для того, чтобы у тебя было более одной opció n. –  09.01.2017, 20:39
  • 3
    using (NpgsqlDataReader reader = cmd. ExecuteReader ()) reader приходит ко мне null –  09.01.2017, 21:03
  • 4
    ¿ Страховка? это prá cticamente невозможный. Обычно, контракт состоит в том, что, или он возвращает тебе reader или бросает в тебя excepció n, но когда бы то ни было deberí чтобы возвращать под тебя null. Это está редкий. –  09.01.2017, 21:05
  • 5
    Мне кажется проблема, что он с синтаксисом, из-за которого db это не интерпретирует поэтому, не вводит меня в reader. –  09.01.2017, 21:54

В постглинистом песчанике связывание - с ||, тогда консультация была бы должна оставаться такой:

cmd.CommandText = @"SELECT IdArticulo, Descripcion FROM tblarticulos
                WHERE ((IdArticulo IS NULL) OR (IdArticulo LIKE '%' || @IdArticulo || '%'))
                AND ((Descripcion IS NULL) OR (Descripcion LIKE '%' || @Descripcion || '%'))";

ты подпираешь стоимость параметра он был бы должен иметь следующую форму:

@IdArticulo => '1'

@Descripcion => 'desc'

таким образом что в конце концов то, что работает на сервере BD, нечто похожее:

SELECT IdArticulo, Descripcion FROM tblarticulos
                    WHERE ((IdArticulo IS NULL) OR (IdArticulo LIKE '%' || '1' || '%'))
                    AND ((Descripcion IS NULL) OR (Descripcion LIKE '%' || 'desc' || '%'))
3
ответ дан 03.12.2019, 17:48

Теги

Похожие вопросы