Как фильтровать записи, содержащие все слова, указанные в базе данных столбцов

#vb.net #sqlite #sqlite-net

#vb.net #sqlite #sqlite-net

Вопрос:

Я знаю, как использовать LIKE оператор и WHERE предложение для поиска указанного шаблона в столбце базы данных. например, "SELECT * From customer WHERE nam like '%" amp; txts amp; "%'" . если txts содержит «Мальчик». Он отображает записи с надписями «Мальчик хороший», «что не так с мальчиком» и т.д. Однако я хочу, чтобы, если txts содержит «мальчик», он также должен отображать записи типа «там находятся девочка и два мальчика», «менеджер пришел с мальчиком». Какой синтаксис / код я могу использовать для достижения этого?

Комментарии:

1. То, что вы хотите, называется полнотекстовым поиском. Прочитайте все это: sqlite.org/fts5.html . (И попробуйте sqlitetutorial.net/sqlite-full-text-search )

2. @Tomalak, я не пользователь SQLite, но я не знал, что он поддерживает полнотекстовый поиск. Это впечатляет меня все больше и больше.

3. @jmcilhinney Это зависит от версии библиотеки. Полнотекстовые возможности встроены в SQLite версии 3.9.0.

Ответ №1:

Однако я хочу, чтобы, если текстовые сообщения содержали «мальчика», в них также отображались записи типа «там находятся девочка и два мальчика», «менеджер пришел с мальчиком». Какой синтаксис / код я могу использовать для достижения этого?

Что-то вроде:

 Dim search = "the boy"
search = "%" amp; search.Replace(" ", "%") amp; "%"

Dim sqlDa = New SQLiteDataAdapter("SELECT * From customer WHERE nam like :n", "your connection string here")
sqlDa.SelectCommand.Parameters.Add("n", SQLiteType.Text, search.Length, search)

Dim dt as New DataTable
sqlDa.Fill(dt)
  

Важной частью является изменение поискового запроса с "the boy" на "%the%boy%" , но я также включил пример того, как использовать параметризованные запросы. Всегда (always всегда) используйте параметризованные запросы. Никогда (никогда в жизни) не существует причины не использовать их.

Руководство по внедрению SQL

Последствия внедрения SQL


Теперь, когда мы прояснили проблему, вы можете либо продолжить модификацию этого метода:

 Dim search = "the boy"

Dim sqlDa = New SQLiteDataAdapter("SELECT * From customer WHERE 1=1 ", "your connection string here")

Dim terms = search.Split()

For i = 0 to UBound(terms)
  Dim term = terms(i)

  sqlDA.SelectCommand.CommandText amp;= $" AND name LIKE :n{i}"
  sqlDa.SelectCommand.Parameters.Add("n" amp; i, SQLiteType.Text, term.Length   2, "%" amp; term amp; "%")

Next i


Dim dt as New DataTable
sqlDa.Fill(dt)
  

Он просто создает SQL, подобный:

 SELECT * From customer WHERE 1=1 AND nam LIKE :n0 AND nam LIKE :n1
'n0 = %the%
'n1 = %boy%
  

Или мы могли бы использовать полнотекстовый поиск; это немного сложнее настроить и поддерживать в актуальном состоянии (взгляните на что-то вродеhttps://hackernoon.com/sqlite-the-unknown-feature-edfa73a6f022) — вы в основном создаете виртуальную таблицу FTS5, которая отслеживает ваше реальное имя таблицы / id и поддерживает ее в актуальном состоянии с помощью триггеров, затем вы можете запросить ее следующим образом:

 Dim search = "the boy"

Dim sqlDa = New SQLiteDataAdapter("SELECT * From customer JOIN fts_customer ON customer.id = fts_customer.id WHERE fts_customer.nam MATCH :s"
sqlDa.SelectCommand.Parameters.Add("s", SQLiteType.Text, search.Length, search)

Dim dt as New DataTable
sqlDa.Fill(dt)
  

Обратите внимание, что в System.Data.Sqlite, похоже, FTS не включен по умолчанию (вы можете получить сообщение об ошибке «такого модуля нет: fts5») — в Microsoft.Data.Sqlite есть, но у него нет адаптера данных (поэтому вам, возможно, придется переключиться на DataTable.Load(sqliteCommand.ExecuteReader()) способ работы

Комментарии:

1.Я попробовал это с помощью SELECT * From customer WHERE 1=1 AND nam LIKE :n0 AND nam LIKE :n1 'n0 = %the% 'n1 = %boy% , и это сработало. Однако, параметризация, как предложено, вызывает у меня проблему. Вставка вашего кода выдает ошибку SQLiteType.Text

2. Может быть, потому, что в nam -> name есть небольшая опечатка? Это тот же код, который, как вы сказали, работал раньше, он просто повторяется один раз для каждого параметра. Посмотрите на SelectComamnd. CommandText и посмотрите, как это выглядит на самом деле. Опубликуйте точное сообщение об ошибке

Ответ №2:

Вот как я с этим справился

 Dim search = "the boy"
   Using sqlconn As New SQLiteConnection(connectionString)
                Dim readN As String = "SELECT id From customer WHERE 1=1 "
                Dim cmd As New SQLiteCommand(readN, sqlconn)
                Dim terms = search.Split()
                For i = 0 To UBound(terms)
                    Dim term = terms(i)
                    cmd.CommandText amp;= $" AND name LIKE :n{i}"
                    cmd.Parameters.AddWithValue(":n" amp; i, "%" amp; term amp; "%")
                Next i
                sqlconn.Open()
                Dim reader As SQLiteDataReader = cmd.ExecuteReader
                While reader.Read
                    For i = 0 To reader.FieldCount - 1
                        MsgBox(reader.GetValue(i))
                    Next
                End While
                sqlconn.Close()
            End Using