2016-09-28 123 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。 非常感謝! –