我目前正在为我的学校项目开发一个T-SQL解析器,它将能够映射数据库中的查询。到目前为止,我已经设法解析大部分,但我有一个问题,我似乎无法解决…我正在使用c#和tsql。g4语法和ANTLR4.
如何访问表达式?我想知道我在select中并且我有某种表达式,但是表达式是什么类型的呢?是否可以从select_statement中仅提取列名、模式(如果有)和数据库(如果有)?
当我试图从c#代码中访问表达式时:
环境:GrammarSQLParser.Dml_clauseContext context
.select_list .query_specification .query_expression context.select_statement () () () () .select_list_elem () .expression ()
我只得到CopyFrom()方法,我没有任何full_column_name()方法来访问进一步的table_name()等.
edit1:仔细检查后,表达式是一个column_ref_expression,但我如何从表达式访问它?它们是不同的对象。
这是查询:
select p.BusinessEntityID,p.FirstName,p.LastName,adresstbl.* from person.Person as p
join (select bea.BusinessEntityID, adr.AddressLine1, adr.AddressLine2, adr.City, adr.PostalCode from person.BusinessEntityAddress as bea
join person.Address as adr
on bea.AddressID = adr.AddressID )
as adresstbl
on not p.BusinessEntityID != adresstbl.BusinessEntityID order by p.BusinessEntityID
这是我的解析树:
Lisp解析树:(tsql_file (batch (sql_clauses (sql_clause .)(dml_clause (select_statement (query_expression)select (select_list (select_list_elem (expression(table_name (id (simple_id p)))。(id (simple_id BusinessEntityID))))) ., (select_list_elem (expression) (full_column_name (table_name (id . s)(simple_id p))。(id (simple_id FirstName))))), (select_list_elem .)(expression (full_column_name (table_name (id (simple_id p)))) .)(id(simple_id LastName))))), ) (select_list_elem (table_name (id . m)(simple_id addresstbl)))。*)) from (table_sources (table_source . stable_source_item_joined (table_source_item(table_name (id (simple_id person))。(id (simple_id Person))))(as_table_alias as (table_alias) id (simple_id p))))) (join_part join .)(table_source_item_joined (table_source_item . joinselect (select) _statement (query_expression)(query_expression (query_specification)(select_list_elem (expression) (full_column_name (table_name)(simple_id bea)))。(id (simple_id BusinessEntityID))))),(select_list_elem (expression) (full_column_name (table_name)(simple_id adr)))。(id (simple_id AddressLine1))))),(select_list_elem (expression) (full_column_name (table_name)(simple_id adr)))。(id (simple_id AddressLine2))))),(select_list_elem (expression) (full_column_name (table_name)(simple_id adr)))。(id (simple_id城市))))),(select_list_elem . 0)(expression (full_column_name (table_name (id (simple_id adr)))) .)(id(simple_id PostalCode)))))) from (table_sourcestable_source_item_joined (table_source_item(table_name (id (simple_id person))。(id (simple_idBusinessEntityAddress)))) (as_table_alias as (table_alias)(simple_id bea)))))) (join_part join (table_source . nettable_source_item_joined (table_source_item(table_name (id (simple_id person))。(id (simple_id地址))))(as_table_alias as (table_alias) (id (simple_id adr))))))))搜索条件(search_condition_and search_condition_not(predicate (expression) full_column_name (table_name (id (simple_id . id)bea)))。(id (simple_id AddressID)))) (comparison_operator =))(expression (full_column_name (table_name (id (simple_id adr)))) .)(id(simple_id AddressID )))))))))))))) ))))) ( as_table_alias作为(table_alias (id (simple_id addresstbl)))))))) on (search_condition . net)(search_condition_and (search_condition_not not)(full_column_name (table_name (id (simple_id p))))。(id (simple_idBusinessEntityID)))) (comparison_operator !)=)(表达式(full_column_name (table_name (id (simple_id addresstbl))) .)(id(simple_id BusinessEntityID)))))))))))))) (order_by_clause order by .(order_by_expression (expression) full_column_name (table_name (id .)(simple_id p))。(id (simple_id BusinessEntityID))))))))))))
)
expression
可能是许多事情之一。如果你看一下语法,你会看到
expression
: DEFAULT #primitive_expression
| NULL #primitive_expression
| LOCAL_ID #primitive_expression
| constant #primitive_expression
| function_call #function_call_expression
| expression COLLATE id #function_call_expression
| case_expr #case_expression
| full_column_name #column_ref_expression
| '(' expression ')' #bracket_expression
| '(' subquery ')' #subquery_expression
| '~' expression #unary_operator_expression
| expression op=('*' | '/' | '%') expression #binary_operator_expression
| op=('+' | '-') expression #unary_operator_expression
| expression op=('+' | '-' | '&' | '^' | '|') expression #binary_operator_expression
| expression comparison_operator expression #binary_operator_expression
;
你需要弄清楚这是哪件事。在您的情况下,它是一个column_ref_expression
,在这种情况下,您需要将其转换为Column_ref_expressionContext
,然后您将能够访问full_column_name
。
有多种方法可以确定它是哪个,或者如果您只想支持语法的有限子集,则可以假设。