Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Microsoft Tsql Scriptdom中的哪个API允许我从SQL脚本检索/存储所有表引用?_C#_Sql Server_Scriptdom - Fatal编程技术网

C# Microsoft Tsql Scriptdom中的哪个API允许我从SQL脚本检索/存储所有表引用?

C# Microsoft Tsql Scriptdom中的哪个API允许我从SQL脚本检索/存储所有表引用?,c#,sql-server,scriptdom,C#,Sql Server,Scriptdom,以下是我引用的MS文档: 我已经看过几次了,但似乎找不到在sql脚本中检索每个表引用的实际名称的位置。NamedTableReference是我找到的最接近的东西,但它只允许您查看表的别名,而我需要实际名称 例如: SELECT * FROM Table1 INNER JOIN Table2 ON Table1.ID = Table2.ID 我希望输出: 表1 表2 最后一部分不一定很重要,但仅限于上下文。。我正在尝试扩展一个开源TSQLLint项目的功能,这将使我能够检查我们公司中开发人员正

以下是我引用的MS文档:

我已经看过几次了,但似乎找不到在sql脚本中检索每个表引用的实际名称的位置。NamedTableReference是我找到的最接近的东西,但它只允许您查看表的别名,而我需要实际名称

例如:

SELECT * FROM Table1 INNER JOIN Table2 ON Table1.ID = Table2.ID
我希望输出: 表1 表2


最后一部分不一定很重要,但仅限于上下文。。我正在尝试扩展一个开源TSQLLint项目的功能,这将使我能够检查我们公司中开发人员正在使用的非常活跃的表名,而无需NOLOCK提示。

您可以使用。片段的
SchemaObject.BaseIdentifier.Value
是引用的表名

下面是一个源于的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将定义基类型的外部程序集加载到应用程序域中,以便编译带有派生类的脚本。这可以通过一个包装器脚本完成,该脚本点源于实际脚本,如:

# 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"

您可以使用一个标记来识别脚本中的所有
NamedTableReference
片段。片段的
SchemaObject.BaseIdentifier.Value
是引用的表名

下面是一个源于的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将定义基类型的外部程序集加载到应用程序域中,以便编译带有派生类的脚本。这可以通过一个包装器脚本完成,该脚本点源于实际脚本,如:

# 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"

但是NOLOCK是邪恶的。我猜这是个玩笑,但是我们有一些非常常用的表,需要NOLOCK提示。当然,我们只对SELECT语句执行此操作,这些语句不会受到脏读的影响。@DylanJanszen,还请注意,read UNCOMMITED可能会导致结果中的行丢失或重复。行版本控制隔离级别是避免阻塞的正确方法。关于
NamedTableReference
片段,我认为
SchemaObject.BaseIdentifier.Value
属性将包含表名。看起来FromClause类实际上可能就是我要查找的。如果这不起作用,我会记下你说的话,并尝试一下。谢谢但是NOLOCK是邪恶的。我猜这是个玩笑,但是我们有一些非常常用的表,需要NOLOCK提示。当然,我们只对SELECT语句执行此操作,这些语句不会受到脏读的影响。@DylanJanszen,还请注意,read UNCOMMITED可能会导致结果中的行丢失或重复。行版本控制隔离级别是避免阻塞的正确方法。关于
NamedTableReference
片段,我认为
SchemaObject.BaseIdentifier.Value
属性将包含表名。看起来FromClause类实际上可能就是我要查找的。如果这不起作用,我会记下你说的话,并尝试一下。谢谢