Поиск с использованием нескольких ключевых слов с параметром в C # SQLite [duplicate]

Члены класса:

Для деструктора pure virtual требуется реализация.

Объявление деструктора по-прежнему требует определения его (в отличие от обычной функции):

struct X
{
    virtual ~X() = 0;
};
struct Y : X
{
    ~Y() {}
};
int main()
{
    Y y;
}
//X::~X(){} //uncomment this line for successful definition

Это происходит потому, что деструкторы базового класса вызывается, когда объект уничтожается неявно, поэтому требуется определение.

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

Это похоже на методы не virtual без определения, с добавлением аргументов, которые генерирует чистая декларация dummy vtable, и вы можете получить ошибку компоновщика без использования функции:

struct X
{
    virtual void foo();
};
struct Y : X
{
   void foo() {}
};
int main()
{
   Y y; //linker error although there was no call to X::foo
}

Чтобы это сработало, объявите X::foo() чистым:

struct X
{
    virtual void foo() = 0;
};

Non- virtual

Некоторые члены должны быть определены, даже если они явно не используются:

struct A
{ 
    ~A();
};

Следующие ошибки приведут к ошибке:

A a;      //destructor undefined

Реализация может быть встроенной в самом определении класса:

struct A
{ 
    ~A() {}
};

или снаружи:

A::~A() {}

Если реализация вне определения класса, но в заголовке, методы должны быть отмечены как inline, чтобы предотвратить множественное определение.

Все используемые методы-члены должны быть определены, если они используются.

Общей ошибкой является отказ от квалификации имени:

struct A
{
   void foo();
};

void foo() {}

int main()
{
   A a;
   a.foo();
}

Определение должно быть

void A::foo() {}

static. Члены данных должны быть определены вне класса в единственная единица перевода:

struct X
{
    static int x;
};
int main()
{
    int x = X::x;
}
//int X::x; //uncomment this line to define X::x

Инициализатор может быть предоставлен для элемента данных static const типа интеграла или перечисления в определении класса; однако odr-использование этого элемента по-прежнему потребует определения области пространства имен, как описано выше. C ++ 11 позволяет инициализировать внутри класса для всех членов static const данных.

5
задан mutiemule 3 December 2013 в 10:07
поделиться

2 ответа

Вы делаете несколько вещей здесь неправильно:

  • Вы даете всем своим параметрам одно и то же имя @searchitem. Это не сработает. Параметры должны иметь уникальные имена.
  • Вы создаете новый SqlCommand для каждого элемента. Это не сработает. Создайте SqlCommand один раз в начале цикла, а затем установите CommandText, как только вы закончите создание SQL.
  • Ваш SQL заканчивается на AND, что недействительно синтаксис.

Предложения по улучшению (не так само по себе, но не лучшая практика):

  • Как предложил Фредерик, обычным способом является установка % в этом параметре, вместо того, чтобы выполнять конкатенацию строк внутри SQL.
  • Если вы явно не используете сортировку с учетом регистра для вашей базы данных, сравнение должно быть нечувствительным к регистру. Таким образом, вам может не понадобиться LOWER.

Пример кода:

SqlCommand cmd = new SqlCommand();
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.Append("SELECT name, memberid FROM members ");

var i = 1;
foreach (string item in keywords)
{
    sqlBuilder.Append(i == 1 ? " WHERE " : " AND ");
    var paramName = "@searchitem" + i.ToString();
    sqlBuilder.AppendFormat(" Name LIKE {0} ", paramName); 
    cmd.Parameters.AddWithValue(paramName, "%" + item + "%");

    i++;
}
cmd.CommandText = sqlBuilder.ToString();
13
ответ дан Heinzi 23 August 2018 в 22:31
поделиться

Не помещайте подстановочные знаки в свой запрос, но добавляйте их к своему параметру-значению:

sql = "SELECT name FROM members WHERE Name LIKE @p_name";
...
cmd.Parameters.AddWithValue("@p_name", "%" + item + "%");

Когда вы добавляете подстановочные знаки внутри строки запроса, параметр будет экранирован, но символы подстановки не будут; это приведет к запросу, который отправляется в БД, который выглядит следующим образом:

SELECT name FROM members WHERE Name LIKE %'somename'%

, что, очевидно, неверно.

Рядом с этим вы создаете SqlCommand в петле, которая не нужна. Кроме того, вы создаете параметры с уникальным именем, так как вы добавляете их в цикл, и параметр всегда имеет одно и то же имя. Вы также должны удалить последнее ключевое слово И, когда вы выходите из цикла.

3
ответ дан Frederik Gheysels 23 August 2018 в 22:31
поделиться
Другие вопросы по тегам:

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