python 函数根据我的内部细节将 SQL 查询从 sqlite 语法转换为 Oracle

问题描述 投票:0回答:1

我想使用 python 将 SQL 查询从 sqlite 语法转换为具有我内部细节的 oracle。该函数将只处理 select 语句。该函数应该接受一个字符串作为输入并返回一个字符串。

函数中处理字符串的逻辑如下:

  1. 如果字符串中包含LIMIT一词,则需要分析它之前的内容。如果查询中有where子句,那么我们需要添加ROWNUM=。如果查询中没有where子句,则必须根据sql子句的顺序规则创建: 选择 从 加入 在哪里 通过...分组 拥有 订购依据 限制

应该考虑到某些子句可能不存在 - GROUP BY、HAVING、ORDER BY 和 JOIN。有必要动态确定 WHERE 子句不存在时应插入的确切位置。

示例: a) '从 zip_data AS T1 内连接中选择 T2.bad_alias 避免 AS T2 ON T1.zip_code = T2.zip_code WHERE T1.avg_house_value = ( SELECT MAX(avg_house_value) FROM zip_data ) LIMIT 1' -> '选择 T2. bad_alias FROM zip_data AS T1 INNER JOIN 避免 AS T2 ON T1.zip_code = T2.zip_code WHERE T1.avg_house_value = ( SELECT MAX(avg_house_value) FROM zip_data ) AND ROWNUM = 1' b) 'SELECT t.state, T1.first_name, T1.last_name FROM zip_data A T INNER JOIN congress AS T1 ON t.state = T1.abbreviation GROUP BY t.state ORDER BY SUM(t.asian_population) DESC LIMIT 3' - > 'SELECT t.state, T1.first_name, T1.last_name FROM zip_data A T INNER JOIN congress AS T1 ON t.state = T1.abbreviation WHERE ROWNUM = 1 GROUP BY t.state ORDER BY SUM(t.asian_population) DESC'

  1. SELECT 和 JOIN 子句中的表别名不应包含 AS,应将其删除

示例:'从 zip_data AS T1 INNER JOIN 中选择 T2.bad_alias 避免在 T1.zip_code = T2.zip_code WHERE T1.avg_house_value = ( SELECT MAX(avg_house_value) FROM zip_data ) AND ROWNUM = 1' -> 'SELECT T2. bad_alias FROM zip_data T1 INNER JOIN 避免 T2 ON T1.zip_code = T2.zip_code WHERE T1.avg_house_value = ( SELECT MAX(avg_house_value) FROM zip_data ) AND ROWNUM = 1''

  1. 从源表(而不是从 CTE)选择的列名称必须用双引号括起来。

示例:'从 zip_data T1 INNER JOIN 中选择 T2.bad_alias 避免 T2 ON T1.zip_code = T2.zip_code WHERE T1.avg_house_value = ( SELECT MAX(avg_house_value) FROM zip_data ) AND ROWNUM = 1' -> 'SELECT T2. 'bad_alias' FROM zip_data T1 INNER JOIN 避免 T2 ON T1.'zip_code' = T2.'zip_code' WHERE T1.'avg_house_value' = ( SELECT MAX('avg_house_value') FROM zip_data ) AND ROWNUM = 1'

我尝试了几种变体,但没有成功。我正在考虑使用一棵树来知道在哪里插入第 1 点中的 where 子句,但到目前为止也没有运气。

python-3.x oracle sqlite
1个回答
0
投票

假设您使用的是 Oracle 12 或更高版本,并且您的查询不包含

LIMIT
作为列名称或文字中,则只需将
\bLIMIT\s+(\d+)\b
替换为
FETCH FIRST \1 ROWS ONLY

© www.soinside.com 2019 - 2024. All rights reserved.