#sql-server #tsql #antlr4
#sql-сервер #tsql #antlr4
Вопрос:
Я использую эти грамматики / лексеры TSql для анализа хранимых процедур в целевом объекте c #.
Я обнаружил, что следующий метод имеет проблемы.
public override void EnterProcedure_param(Procedure_paramContext context)
{
string txt = context.GetText();
string datatype = context.data_type().GetText();
if (IsUserDefinedType(datatype)) // not shown
DoSomething(datatype);
}
Он будет правильно извлекать тип данных (и txt) при определении хранимой процедуры :
CREATE PROCEDURE [dbo].[PROC_SomeProc]
@APPINSTID BIGINT
AS ...
но НЕ
CREATE PROCEDURE [dbo].[PROC_SomeProc]
@AppInstId BIGINT
AS ...
В последнем случае txt — это ‘@AI’, а тип данных — ‘I’.
Кроме того, если параметр определен @appinstid
, метод никогда не посещается.
Означает ли это, что грамматика должна быть неисправна или, возможно, я что-то упускаю?
Комментарии:
1. Я предлагаю вам открыть проблему в проекте github . У меня был хороший успех при разборе T-SQL с Microsoft.SQLServer. Transactsql.ScriptDom на C # и PowerShell, доступный в пакете DacFx NuGet .
2. В примечании на главной странице четко указано: «Поскольку грамматика SQL обычно не чувствительна к регистру, но эта реализация грамматики …»
3. @SMor — так и есть. Я пропустил это при обновлении с более ранней грамматики non_cs.
Ответ №1:
Используйте CaseChangingCharStream
вместо стандартного потока токенов. Смотрите подробности здесь:https://github.com/antlr/antlr4/blob/master/doc/case-insensitive-lexing.md
Комментарии:
1. В реализации C # CaseChangingCharStream обнаружена ошибка — строки 71 и 73 ‘LA’ должны быть ‘La’. Спасибо за вашу помощь.
2. Это не ошибка — это зависит от времени выполнения C #: стандартное или оптимизированное.