3

我见过几个类似的线程,但尝试转义字符对我不起作用。

简而言之,我有一个字符串列表,我正在对其进行迭代,因此我的目标是构建一个查询,该查询将列表中的许多字符串合并到一个“选择,喜欢”查询中。

这是我的代码(Python)

def myfunc(self, cursor, var_list):
   query = "Select var FROM tble_tble WHERE"
   substring = []
   length = len(var_list)
   iter = length

   for var in var_list:
      if (iter != length):
         substring.append(" OR tble_tble.var LIKE %'%s'%" % var)
      else:
         substring.append(" tble_tble.var LIKE %'%s'%" % var)
      iter = iter - 1

   for str in substring:
      query = query + str
...

这应该足够了。如果从我之前声明的声明中不明显,我正在尝试构建一个查询,该查询在相关字符串列表中运行 SQL 'LIKE'比较。

感谢您的宝贵时间,请随时提出任何问题以进行澄清。

4

3 回答 3

11

首先,您的问题与 SQL 无关。丢弃所有与 SQL 相关的代码并执行以下操作:

var = 'foo'
" OR tble_tble.var LIKE %'%s'%" % var

你会得到同样的错误。这是因为您正在尝试%使用带有杂散%符号的字符串进行格式化。因此,它试图弄清楚如何处理%',但失败了。


您可以像这样逃避这些杂散%的迹象:

" OR tble_tble.var LIKE %%'%s'%%" % var

但是,这可能不是您想要做的。


首先,考虑使用{}-formatting 而不是%-formatting,尤其是当您尝试构建带有%字符的格式化字符串时。它避免了逃避它们的需要。所以:

" OR tble_tble.var LIKE %'{}'%".format(var)

但是,更重要的是,您根本不应该进行这种格式化。不要将值格式化为 SQL 字符串,只需将它们作为 SQL 参数传递。如果您使用的是 sqlite3,请使用?参数标记;对于 MySQL %s,; 对于不同的数据库,请阅读其文档。所以:

" OR tble_tble.var LIKE %'?'%"

这里没有什么可以出错的,也没有什么需要逃避的。当您execute使用查询字符串调用时,作为参数传递[var]

这要简单得多,而且通常更快,并且巧妙地避免了许多处理边缘情况的愚蠢错误,最重要的是,它可以防止 SQL 注入攻击。

sqlite3 文档更详细地解释了这一点:

通常,您的 SQL 操作将需要使用 Python 变量中的值。您不应该使用 Python 的字符串操作来组装您的查询……而是使用 DB-API 的参数替换。将?作为占位符放在要使用值的任何位置,然后提供一个值元组作为游标execute()方法的第二个参数。(其他数据库模块可能使用不同的占位符,例如 %s 或 :1。)……</p>


最后,正如其他人在评论中指出的那样,在LIKE有条件的情况下,您必须将百分号放在引号内,而不是放在引号。所以,无论你用哪种方式解决这个问题,你都会有另一个问题要解决。但这应该容易得多。(如果没有,你可以随时回来问另一个问题。)

于 2013-08-01T19:18:53.663 回答
0

您需要%像这样转义,您需要更改引号以包含两者%生成正确的 SQL

" OR tble_tble.var LIKE '%%%s%%'"

例如:

var = "abc"
print " OR tble_tble.var LIKE '%%%s%%'" % var

它将被翻译成:

OR tble_tble.var LIKE '%abc%'
于 2013-08-01T19:19:47.853 回答
0

这是一个老问题,所以这是我必须做的,以使这项工作与上述所有软件的最新版本一起工作:

citp = "SomeText" + "%%"  # if your LIKE wants database rows that match start text, else ... 
citp = "%%" + "SomeQueryText" + "%%"   

        chek_copies = 'SELECT id, code, null as num from indicator WHERE code LIKE "%s" AND owner = 1 ;'
        check_copies = (chek_copies % (citp))
        copies_checked = pd.read_sql(check_copies, con=engine)

像魅力一样工作 - 但需要大量的试验和错误

于 2020-07-31T00:07:06.347 回答