Какой API в Microsoft T sql Scriptdom позволит мне получить / сохранить ВСЕ ссылки на таблицы из сценария SQL? - PullRequest
1 голос
/ 26 января 2020

Вот MS do c, на который я ссылаюсь: https://docs.microsoft.com/en-us/dotnet/api/microsoft.sqlserver.transactsql.scriptdom?view=sql-dacfx-140.3881.1

Я уже просматривал это несколько раз, но не могу найти, где я могу чтобы получить фактическое имя каждой ссылки на таблицу в скрипте sql. NamedTableReference - самая близкая вещь, которую я нашел, но она позволяет вам видеть псевдонимы таблицы, тогда как я хочу фактическое имя.

Пример:

SELECT * FROM Table1 INNER JOIN Table2 ON Table1.ID = Table2.ID

Я хотел бы получить вывод : Table1 Table2

Эта последняя часть не обязательно важна, но только для контекста. Я пытаюсь расширить функциональность проекта TSQLLint с открытым исходным кодом и это даст мне возможность проверять очень активные имена таблиц в нашей компании, которые использует разработчик, без подсказки NOLOCK.

1 Ответ

2 голосов
/ 26 января 2020

Вы можете идентифицировать все NamedTableReference фрагменты в скрипте, используя шаблон посетителя . SchemaObject.BaseIdentifier.Value фрагмента - это имя таблицы, на которую ссылаются.

Ниже приведен пример PowerShell, полученный из TSqlConcreteFragmentVisitor. Это может быть адаптировано для. NET языка по вашему выбору.

$script = @"
SELECT * FROM Table1 INNER JOIN Table2 as t2 ON Table1.ID = Table2.ID
"@

class MyVisitor: Microsoft.SqlServer.TransactSql.ScriptDom.TSqlConcreteFragmentVisitor {

    [void]Visit ([Microsoft.SqlServer.TransactSql.ScriptDom.NamedTableReference] $fragment) {
            Write-Host "Found $($fragment.GetType().Name) at line $($fragment.StartLine), column $($fragment.StartColumn). Table name: $($fragment.SchemaObject.BaseIdentifier.Value)"
    }

}

# ############
# ### MAIN ###
# ############

try {

    $parser = New-Object Microsoft.SqlServer.TransactSql.ScriptDom.TSql150Parser($true)
    $parseErrors = New-Object System.Collections.Generic.List[Microsoft.SqlServer.TransactSql.ScriptDom.ParseError]
    $stringReader = New-Object System.IO.StringReader($script)

    $frament = $parser.Parse($stringReader, [ref]$parseErrors)
    if($parseErrors.Count -gt 0) {
        throw "$($parseErrors.Count) parsing errors: $(($parseErrors | ConvertTo-Json))"
    }

    $visitor = [MyVisitor]::new()

    $frament.Accept($visitor)

}
catch {
    throw
}

Вывод:

Found NamedTableReference at line 1, column 15. Table name: Table1.
Found NamedTableReference at line 1, column 33. Table name: Table2.

В PowerShell сначала необходимо загрузить внешнюю сборку, которая определяет базовый тип, в домен приложения, используя Add-Type, чтобы скрипт с производным класс скомпилируется. Это может быть сделано с помощью скрипта-обёртки, который поставляет точный исходный текст скрипта, например:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...