Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 字符串字段包含其他字符串的EXTO查询_Elixir_Sql Like_Ecto - Fatal编程技术网

Elixir 字符串字段包含其他字符串的EXTO查询

Elixir 字符串字段包含其他字符串的EXTO查询,elixir,sql-like,ecto,Elixir,Sql Like,Ecto,我正在构建一个简单的搜索功能,我想在字符串字段中查找所有包含字符串的记录 以下是我所尝试的 term = "Moby" MyApp.Book |> where([p], String.contains?(p, term)) |> order_by(desc: :inserted_at) 这将返回以下书籍: 白鲸 桑迪奇·莫比·莱恩 我的Mobyand例子 但我得到: `String.contains?(p, term)` is not a valid query expressio

我正在构建一个简单的搜索功能,我想在字符串字段中查找所有包含字符串的记录

以下是我所尝试的

term = "Moby"
MyApp.Book
|> where([p], String.contains?(p, term))
|> order_by(desc: :inserted_at)
这将返回以下书籍:

白鲸 桑迪奇·莫比·莱恩 我的Mobyand例子 但我得到:

`String.contains?(p, term)` is not a valid query expression
以下是您的操作方法:

results = 
  from b in Book,
  where: ilike(t.name, ^"%#{params["term"]}%"),
  order_by: [desc: :inserted_at]
以下是您的操作方法:

results = 
  from b in Book,
  where: ilike(t.name, ^"%#{params["term"]}%"),
  order_by: [desc: :inserted_at]
如果由最终用户输入,则必须使用String.replace/3对输入中的%进行转义,然后在查询中使用like:

|> where([p], like(p.title, ^"%#{String.replace(term, "%", "\\%")}%"))
例如:

iex(1)> term = "Foo%Bar"
iex(2)> query = MyApp.Post |> where([p], like(p.title, ^"%#{String.replace(term, "%", "\\%")}%")) |> order_by(desc: :inserted_at)
#Ecto.Query<from p in MyApp.Post, where: like(p.title, ^"%Foo\\%Bar%"),
 order_by: [desc: p.inserted_at]>
iex(3)> Ecto.Adapters.SQL.to_sql(:all, MyApp.Repo, query)
{"SELECT p0.\"id\", p0.\"title\", p0.\"user_id\", p0.\"inserted_at\", p0.\"updated_at\" FROM \"posts\" AS p0 WHERE (p0.\"title\" LIKE $1) ORDER BY p0.\"inserted_at\" DESC",
 ["%Foo\\%Bar%"]}
如果不进行替换,则像%b这样的术语将与azb匹配,因为%需要转义,或者它与零或多个字符的任何序列匹配。

如果最终用户输入了%,则必须使用String.replace/3来转义输入中的%,然后在查询中使用like:

|> where([p], like(p.title, ^"%#{String.replace(term, "%", "\\%")}%"))
例如:

iex(1)> term = "Foo%Bar"
iex(2)> query = MyApp.Post |> where([p], like(p.title, ^"%#{String.replace(term, "%", "\\%")}%")) |> order_by(desc: :inserted_at)
#Ecto.Query<from p in MyApp.Post, where: like(p.title, ^"%Foo\\%Bar%"),
 order_by: [desc: p.inserted_at]>
iex(3)> Ecto.Adapters.SQL.to_sql(:all, MyApp.Repo, query)
{"SELECT p0.\"id\", p0.\"title\", p0.\"user_id\", p0.\"inserted_at\", p0.\"updated_at\" FROM \"posts\" AS p0 WHERE (p0.\"title\" LIKE $1) ORDER BY p0.\"inserted_at\" DESC",
 ["%Foo\\%Bar%"]}

如果不进行替换,则像%b这样的术语将匹配azb,因为%需要转义,或者它匹配任何零或多个字符的序列。

您可以这样做,并向SQL注入攻击打招呼。按MattW的方式执行。@JustMichael他需要在用户给定的术语前后添加%,否则他会怎么做?@JustMichael这里没有SQL注入,但如果参数[term]包含任何%,它们将被视为匹配零个或更多字符的任何序列。此外,MattW当前的代码也无法工作。您可以这样做,并向SQL注入攻击问好。按MattW的方式执行。@JustMichael他需要在用户给定的术语前后添加%,否则他会怎么做?@JustMichael这里没有SQL注入,但如果参数[term]包含任何%,它们将被视为匹配零个或更多字符的任何序列。另外,马特目前的代码也不起作用。我希望我能在StackOverflow上跟踪用户。长生不老药宝库:拇指支撑:你也应该转义下划线,它匹配任何一个字符。我希望我能在StackOverflow上跟踪用户。长生不老药宝库:拇指支撑:您还应该转义下划线,它匹配任何单个字符。