2016-09-28 203 views
1

我目前正在开发一个T-SQL解析器,它能够将我的学校项目的查询映射到数据库中。到目前为止,我已经设法解析它的大部分,但我有一个问题,我似乎无法解决..我使用C#与tsql.g4语法和ANTLR4。使用ANTLR4解析T-SQL查询

如何访问表达式?我想知道我在选择而且我有某种表达方式,但表达方式是什么样的表达方式?是否可以从select_statement中仅提取列名,模式(如果有的话)和数据库(如果有的话)?

每当我尝试从C#代码访问表达

上下文:。GrammarSQLParser.Dml_clauseContext context context.select_statement()query_expression()query_specification()select_list中()select_list_elem()表达式()。

我只得到该方法的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(批次(sql_clauses(sql_clause (dml_clause (select_statement(query_expression(query_specification select(select_list(select_list_elem(expression(full_column_name (table_name(id(simple_id p)))。(id(simple_id Business EntityID))))) ,(select_list_elem(expression(full_column_name(table_name(id (simple_id p)))。 (ID(simple_id姓))))),(select_list_elem (表达(full_column_name(TABLE_NAME(ID(simple_id P)))。(ID (simple_id名字))))),(select_list_elem(TABLE_NAME(从ID (simple_id adresstbl)))。*))(table_sources(table_source (table_source_item_joined(table_source_item(table_name_with_hint (表名(ID(simple_id人))。(ID(simple_id人)))) (as_table_alias为(table_alias(id(simple_id p)))))(join_part join (table_source(table_source_item_joined(table_source_item) (derived_table(subquery(select_statement(query_expressio n( (query_expression(query_specification select(select_list (select_list_elem(expression(full_column_name(table_name(id (simple_id bea)))。 (select_list_elem(表达式(full_column_name(table_name(id)(id(simple_id AddressLine1))))), (select_list_elem(expression(full_column_name (id) (simple_id adr)))。(id(simple_id AddressLine2))))), (select_list_elem(expression(full_column_name(table_name(id (simple_id adr)))。(ID(simple_id市))))),(select_list_elem (表达式(full_column_name(TABLE_NAME(ID(simple_id ADR)))。(ID (simple_id POSTALCODE))从(table_sources(table_source (table_source_item_joined))))( table_source_item(table_name_with_hint (表名(ID(simple_id人))。(ID(simple_id BusinessEntityAddress))))(as_table_alias为(table_alias(ID (simple_id BEA)))))(join_part加入(table_source (table_source_item_joined(table_source_item (table_name_with_hint (table_name(id(simple_id person))。(id(simple_id Address)))) (as_table_alias as(table_alias(id(simple_id adr))))))on (search_condition(search_condition_and(search_condition_not) (predicate(expression(full_column_name(table_name(id(simple_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 as(table_alias(id(simple_id adresstbl)))))))on(search_condition (search_condition_and(search_condition_not not(predicate(expression (full_column_name(table_name(id(simple_id p)))。( ID(简单_id BusinessEntityID)))) (order_by_clause order by (order_by_expression(expression(full_column_name(table_name(id (simple_id p)))。(id(simple_id Bu sinessEntityID))))))))))))

回答

1

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

有很多种方法可以确定它是哪一种,或者你可以假设你是否只想支持语法的有限子集。

+0

这太明显了!我尝试使用context.select_statement()。query_expression()。query_specification()。select_list()。select_list_elem()。expression()的参数创建一个像GrammarSQLParser.Column_ref_expressionContext这样的新对象,并且该对象始终为null。 非常感谢! –