【问题标题】:Getting data from Oracle table where two columns equal separate lists从两列等于单独列表的 Oracle 表中获取数据
【发布时间】:2021-12-21 18:29:44
【问题描述】:

我正在使用 python 从 ORACLE 表中提取数据。我可以使用

提取其中一个列表所需的行
office_list = [aaa, aab, aac, aad]  

&& 实际列表要长得多

"""
SELECT * 
  FROM (
        SELECT distinct(id) as id, 
               office, 
               cym,
               type
          FROM oracle1.table1
         WHERE office IN ({0})
        ) 
""".format("'" + "','".join([str(i) for i in office_list]) + "'")

我不知道如何同时包含来自不同列表的另一个过滤器。

在这种情况下,它是一个类型列表

type_list = [type1, type2, type3, type4]

任何帮助将不胜感激。 谢谢

【问题讨论】:

  • 不要使用字符串连接来构建查询。如果有人决定传入office_list = ["',(SELECT COUNT(1) FROM secrets_table WHERE username = 'Admin' and password_hash='ABCDEF'),'"],那么你就有问题了。
  • 感谢您的反馈。我忘了提到我必须使用中间程序来访问数据......所以需要字符串格式。谢尔盖的反应奏效了。

标签: python sql oracle filtering


【解决方案1】:

在 cx_oracle 中,pass collections to the query。使用绑定变量将有助于防止 SQL 注入攻击,并允许 SQL 引擎为不同的列表重用执行计划,从而提供更高的性能(相反,使用字符串连接会使您的代码容易受到 SQL 注入攻击,并且不允许重新使用使用执行计划)。

在 SQL 中:

CREATE OR REPLACE TYPE string_list AS TABLE OF VARCHAR2(25);
/

在 Python 中:

list_type = connection.gettype("STRING_LIST")

office_list = list_type.newobject()
office_list.extend(["aaa", "aab", "aac", "aad"])

type_list = list_type.newobject()
type_list.extend(["xxx", "xxy", "xxz", "xyz"])

cursor.execute(
    """SELECT DISTINCT
           id,         -- DISTINCT is NOT a function.
           office, 
           cym,
           type
    FROM   oracle1.table1
    WHERE  office in (SELECT column_value FROM TABLE(:1))
    AND    type   in (SELECT column_value FROM TABLE(:2))""",
    [office_list, type_list],
)
for row in cursor:
    print(row)

您可以将WHERE 子句简化为:

WHERE  office MEMBER OF TABLE(:1)
AND    type   MEMBER OF TABLE(:2)

【讨论】:

  • 感谢您的反馈。我忘了提到我必须使用中间程序来访问数据......所以需要字符串格式。谢尔盖的反应奏效了。
【解决方案2】:

"""select * from(
    select
                     distinct(id) as id, 
                     office, 
                     cym,
                     type
                     from oracle1.table1
                     where office in ({0})
                       and type in ({1})
                 ) 
""".format("'" + "','".join(office_list) + "'", "'" + "','".join(type_list) + "'")

【讨论】:

  • 不要使用字符串连接来构建查询。如果有人决定传入type_list = ["',(SELECT COUNT(1) FROM secrets_table WHERE username = 'Admin' and password_hash='ABCDEF'),'"],那么你就有问题了。
  • SQL注入问题是单独的问题)) PS:另外,它们可能不存在,你不知道列表是如何由type_list形成的。它不一定是网站上的表格,必须相应地处理表格。
  • 无论如何数据都应该作为数据(=绑定变量)传​​递,而不是作为 SQL 语句 text 的一部分。连接语句也需要非常长的解析时间。
  • 感谢您的反馈。访问数据需要字符串...我忘了包括那个...有一个中间程序以我提供的格式使用字符串。谢尔盖的回放效果很好。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-20
  • 1970-01-01
  • 1970-01-01
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多