Microsoft Tsql Scriptdom 中的哪个 API 允许我 retrieve/store 来自 SQL 脚本的所有 table 引用?
Which API in the Microsoft Tsql Scriptdom will allow me to retrieve/store ALL table references from a SQL script?
这是我引用的 MS 文档:https://docs.microsoft.com/en-us/dotnet/api/microsoft.sqlserver.transactsql.scriptdom?view=sql-dacfx-140.3881.1
我已经仔细查看了好几遍,但似乎无法找到可以在 sql 脚本中检索每个 table 引用的实际名称的位置。 NamedTableReference 是我发现的最接近的东西,但它只允许您看到 table 的别名,而我想要的是实际名称。
示例:
SELECT * FROM Table1 INNER JOIN Table2 ON Table1.ID = Table2.ID
我想要一个输出:
表1
表2
这最后一部分不一定重要,但仅供参考。我正在尝试扩展开源 TSQLLint 项目的功能,这将使我能够检查非常活跃的 table我们公司中开发人员在没有 NOLOCK 提示的情况下使用的名称。
您可以使用 visitor pattern 识别脚本中的所有 NamedTableReference
片段。片段的 SchemaObject.BaseIdentifier.Value
是引用的 table 名称。
下面是一个派生自 TSqlConcreteFragmentVisitor
的 PowerShell 示例。这可以适应您选择的 .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 将定义基类型的外部程序集加载到应用程序域中,这样具有派生 class 的脚本才能编译。这可以通过包装器脚本来完成,该脚本对实际脚本进行点源处理,例如:
# example wrapper script to load script DOM assembly and execute the visitor script
Add-Type -Path "C:\DacFxAssemblies\Microsoft.SqlServer.TransactSql.ScriptDom.dll"
. "C:\Scripts\Find-NamedTableReferences.ps1"
这是我引用的 MS 文档:https://docs.microsoft.com/en-us/dotnet/api/microsoft.sqlserver.transactsql.scriptdom?view=sql-dacfx-140.3881.1
我已经仔细查看了好几遍,但似乎无法找到可以在 sql 脚本中检索每个 table 引用的实际名称的位置。 NamedTableReference 是我发现的最接近的东西,但它只允许您看到 table 的别名,而我想要的是实际名称。
示例:
SELECT * FROM Table1 INNER JOIN Table2 ON Table1.ID = Table2.ID
我想要一个输出: 表1 表2
这最后一部分不一定重要,但仅供参考。我正在尝试扩展开源 TSQLLint 项目的功能,这将使我能够检查非常活跃的 table我们公司中开发人员在没有 NOLOCK 提示的情况下使用的名称。
您可以使用 visitor pattern 识别脚本中的所有 NamedTableReference
片段。片段的 SchemaObject.BaseIdentifier.Value
是引用的 table 名称。
下面是一个派生自 TSqlConcreteFragmentVisitor
的 PowerShell 示例。这可以适应您选择的 .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 将定义基类型的外部程序集加载到应用程序域中,这样具有派生 class 的脚本才能编译。这可以通过包装器脚本来完成,该脚本对实际脚本进行点源处理,例如:
# example wrapper script to load script DOM assembly and execute the visitor script
Add-Type -Path "C:\DacFxAssemblies\Microsoft.SqlServer.TransactSql.ScriptDom.dll"
. "C:\Scripts\Find-NamedTableReferences.ps1"