【发布时间】:2021-06-28 14:57:29
【问题描述】:
Microsoftlists 3 种不同的方式来获取视图的定义 在 SQL Server 中(另见 this StackOverflow 问题),f.e.
SELECT definition
FROM sys.sql_modules
WHERE object_id = OBJECT_ID('MY.TEST_VIEW');
但它们都在输出中包含CREATE VIEW(这通常很好),我需要确切的查询,即 for
CREATE VIEW [MY].[TEST_VIEW] (COL /*unfortunately some comment containing `as` and brackets :) */)
AS
SELECT 1
我只想要
SELECT 1
虽然总是可以编写一个小的解析器来在视图定义中找到正确的AS,但我更喜欢类似于 Oracle 的 DBA_VIEWS 的东西:
select TEXT from DBA_VIEWS where OWNER = 'MY' and VIEW_NAME = 'TEST_VIEW'
更新 Answer from Dan Guzman 翻译成 vb.net
Imports System.Runtime.Serialization
Imports Microsoft.SqlServer.TransactSql.ScriptDom
<CLSCompliant(False)>
Public Class ViewSelectStatementExtractor : Inherits TSqlFragmentVisitor
Private SelectStatement As String
'visitor method invoked for each CREATE VIEW statement in script
Public Overrides Sub Visit(fragment As CreateViewStatement)
Dim selectStatementFragment = fragment.SelectStatement
'extract SELECT statement text from tokens
Using sw = New IO.StringWriter
For i = selectStatementFragment.FirstTokenIndex To selectStatementFragment.LastTokenIndex
sw.Write(selectStatementFragment.ScriptTokenStream(i).Text)
Next
Me.SelectStatement = sw.ToString()
End Using
End Sub
'Get view SELECT statement Using T-SQL script dom parser and visitor
Shared Function Extract(createViewStatement As String) As String
Dim parser = New Microsoft.SqlServer.TransactSql.ScriptDom.TSql150Parser(True)
Dim parseErrors As IList(Of ParseError) = New List(Of ParseError)
Dim fragment As TSqlFragment
Using stringReader = New IO.StringReader(createViewStatement)
fragment = parser.Parse(stringReader, parseErrors)
End Using
If (parseErrors.Count > 0) Then
Dim errorStrings = From e In parseErrors Select $"{e.Line},{e.Column}: {e.Message}"
Throw New ParseTSqlException($"{parseErrors.Count} parsing errors: {vbNewLine}{String.Join(vbNewLine, errorStrings)}")
End If
Dim visitor = New ViewSelectStatementExtractor
fragment.Accept(visitor)
Return visitor.SelectStatement
End Function
End Class
<Serializable>
Public Class ParseTSqlException
Inherits Exception
Public Sub New()
End Sub
Public Sub New(message As String)
MyBase.New(message)
End Sub
Public Sub New(message As String, innerException As Exception)
MyBase.New(message, innerException)
End Sub
Protected Sub New(info As SerializationInfo, context As StreamingContext)
MyBase.New(info, context)
End Sub
End Class
【问题讨论】:
-
我相信您可以检索到的所有定义都包括完整的定义。
-
您可以使用 T-SQL 脚本 DOM 从视图中提取 select 语句。
-
@DanGuzman 你的意思是来自 Microsoft.SqlServer.TransactSql.ScriptDom 的 TSqlParser.Parse 吗? (docs.microsoft.com/en-us/dotnet/api/…) 我想这会让我免于自己编写“评论解析器”,但代价是额外的依赖。
标签: sql-server