Мне нужно взять хранимую процедуру Teradata и извлечь различные объекты (таблицы, представления, процедуры), используемые в ней. Для этого мне нужно написать синтаксический анализатор для анализа различных запросов SQL, таких как SELECT, MERGE, UPDATE и т. Д.
Также не рекомендуется использовать стороннюю библиотеку.
Я никогда раньше не реализовывал парсер, и поэтому мне хотелось бы получить несколько советов о том, как лучше всего реализовать парсер SQL.
- Я просматривал некоторые существующие ссылки на стек-потоки, и в основном предлагалось использовать pyparsing или Python-sqlparse.
- Могу ли я написать парсер, используя только регулярные выражения? Я не достаточно уверен, так как есть много способов, которыми можно написать запрос, и может ли регулярное выражение обрабатывать все случаи?
- Если pyparsing является наиболее предпочтительным решением, насколько сложно понять и определить в нем грамматику sql?
Я взял ссылку с сайта и написал следующий код для разбора запросов SELECT
def tables_in_sel_query(sql_str):
# Comma shall be prefixed and suffixed with a space
sql_str = re.sub(r'\s*?,'," , ",sql_str,re.I|re.S)
#Remove whitespaces after .
sql_str = re.sub(r'(.+?)\.\s+?',r'\1.',sql_str,re.I)
# remove the /* */ comments
q = re.sub(r"/\*[^*]*\*+(?:[^*/][^*]*\*+)*/", "", sql_str)
# split on blanks, parens and semicolons
tokens = re.split(r"[\s)(;]+", q)
# scan the tokens. if we see a FROM or JOIN, we set the get_next
# flag, and grab the next one (unless it's another keyword).
result = []
get_next = False
for tok in tokens:
if get_next:
if tok.lower() not in
["","select","order","group","where","inner","left","right","on"]:
if (tok != ",") and tok.count(".") > 0:
result.append(tok.strip(","))
else:
get_next = False
continue
get_next = tok.lower() in ["from", "join"]
return result
Хотя это работает нормально, но мне нужно реализовать такую функцию для каждого из типов запросов. Кто-нибудь может предложить наилучший из возможных подходов?