我正在開發一個 SQL 分析工具,給定一個 RAW SQL SELECT 查詢,它可以進行某種分析。該工具的第一個版本已經完成,可以分析簡單的 RAW 查詢。但是,當查詢包含子查詢時,它會中斷。
所以我正在尋找一種簡單但可靠的方法來決議查詢和子查詢。我的工具必須單獨分析每個子查詢,例如:
假設這是工具作為輸入給出的查詢:
SELECT name, email
FROM (SELECT * FROM user WHERE email IS NOT NULL)
WHERE id IN (SELECT cID FROM customer WHERE points > 5)
然后我想得到一個這樣的查詢串列:
queries = [
"SELECT name, EMAIL FROM <subquery> WHERE id in <subquery>"
"SELECT * FROM user WHERE email IS NOT NULL"
"SELECT cID FROM customer WHERE points > 5)"
]
在我的第一次嘗試中,我使用了子查詢總是寫在括號之間的事實。所以我掃描了括號的初始查詢。這在子查詢沒有嵌套時有效,即子查詢中沒有子查詢。我也用 AST 做了一些實驗,但覺得可能有點太復雜了,可能還有更簡單的方法。
誰能指導我正確的方向?我正在使用 Python,但也非常感謝其他語言的示例。
uj5u.com熱心網友回復:
您可以使用sqlparse:
import sqlparse
def queries(d):
if type(d) != sqlparse.sql.Token:
paren = isinstance(d, sqlparse.sql.Parenthesis)
v = [queries(i) for i in (d if not paren else d[1:-1])]
subseq, qrs = ''.join(str(i[0]) for i in v), [x for _, y in v for x in y]
if [*d][paren].value == 'SELECT':
return '<subquery>', [subseq] qrs
return subseq, qrs
return d, []
s="""SELECT name, email
FROM (SELECT * FROM user WHERE email IS NOT NULL)
WHERE id IN (SELECT cID FROM customer WHERE points > 5)
"""
_, subqueries = queries(sqlparse.parse(s)[0])
輸出:
['SELECT name, email\n FROM <subquery>\n WHERE id IN <subquery>\n', 'SELECT * FROM user WHERE email IS NOT NULL', 'SELECT cID FROM customer WHERE points > 5']
使用該sqlparse庫,您可以將 SQL 輸入字串決議為關鍵字、陳述句和值的標記化流。上面的函式queries接受一個sqlparse.sql.Statement物件并搜索查詢中出現的任何SELECT陳述句,并根據所需的輸出樣本重新格式化原始輸入以洗掉子查詢。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/473581.html
上一篇:如何將JSON決議值保存到ArduinoJson中的陣列中
下一篇:從字串中提取所有帶小數的數字
