【问题标题】:VB - Get the strings inside IN statementVB - 获取 IN 语句中的字符串
【发布时间】:2015-05-14 13:40:54
【问题描述】:

在 .Net 2.0 中使用 VB,我想创建一个简单的程序,从我用这样的视图创建的脚本(文本文件)中生成 xml 文件:

USE [Archive-FIRSTVIEW]
GO
/****** Object:  View [dbo].[vABCDEFG]    Script Date: 5/14/2015 8:01:58 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW [dbo].[vABCDEFG]
AS
SELECT        dbo.[Document].docGUID, dbo.[Document].accountGUID, dbo.[Document].jobGUID, dbo.[Document].DOC9docID, dbo.[Document].docDate, dbo.[Document].docType, 
                     dbo.[Document].docPages, dbo.[Document].tsCreated
FROM            dbo.AcctLookupKey INNER JOIN
                     dbo.[Document] ON dbo.AcctLookupKey.docGUID = dbo.[Document].docGUID
WHERE        (dbo.AcctLookupKey.ix = 3) AND (dbo.AcctLookupKey.val IN ('ABCDEFG'))


GO
/****** Object:  View [dbo].[vLMNOP]    Script Date: 5/14/2015 8:01:58 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


CREATE VIEW [dbo].[vLMNOP] AS


SELECT        dbo.[Document].*
FROM            dbo.AcctLookupKey INNER JOIN  dbo.[Document] ON dbo.AcctLookupKey.docGUID = dbo.[Document].docGUID
WHERE        (dbo.AcctLookupKey.ix = 3) 
AND (dbo.AcctLookupKey.val in ('LMNOP','LMNOP (AEIOU)'))

我只想检索每个 WHERE 行末尾的文本,例如,第一个检索“ABCDEFG”,第二个检索“LMNOP”、“LMNOP (AEIOU)”

感谢您的帮助!

编辑: 我想创建一个看起来像这样的 XML 文件:

<Views Code="FIRSTVIEW">
    <View Name="vABCDEFG">
        <Criteria>ABCDEFG</Criteria>
    </View>
    <View Name="LMNOP">
        <Criteria>LMNOP</Criteria>
        <Criteria>LMNOP (AEIOU)</Criteria>
    </View>
<Views>

EDIT2: 到目前为止,能够开始提取一些数据,只是不是我想要的样子。这是在将其加载到 xml 之前。

Dim dir As New DirectoryInfo("d:\input")
    Dim sw As New StreamWriter("d:\input\extract.txt")

    For Each fi As FileInfo In dir.GetFiles("views.txt")
        Dim sr As New StreamReader(fi.FullName)
        Dim root As String
        Dim child As String
        Dim substring As String
        While Not sr.EndOfStream
            Dim sLine As String = sr.ReadLine

            If sLine.Contains("USE [") Then
                root = sLine '.Substring(13) - 1
            End If

            If sLine.Contains("CREATE VIEW") Then
                child = sLine '.Substring(19) - 1
            End If

            If sLine.Contains("(''") Then
                substring = sLine
            End If

            sw.WriteLine(root)
            sw.WriteLine(child)
            sw.WriteLine(substring)
        End While
        sr.Close() : sr.Dispose()
    Next
    sw.Flush() : sw.Close() : sw.Dispose()

【问题讨论】:

  • 我不明白你想在这里做什么。你能试着澄清一下吗?
  • @Sean Lange,我会很快更新我的帖子。
  • 我会改变你的问题,而是问“我想获取 IN 语句中的字符串”
  • 似乎是一个非常脆弱且容易出错的尝试。快速搜索发现sql parser 说它创建了 sql 脚本的 xml 解析树。也许你可以这样做并挖掘出你感兴趣的元素。
  • 你能理解我的回答吗?如果有帮助,请将其标记为答案。

标签: sql-server xml vb.net views


【解决方案1】:

这很 hacky,但它让你知道去哪里。使用 Microsoft.SqlServer.TransactSQL.ScriptDom 库来分析 TSQL。可能比在输入中查找特定字符串更可靠/更灵活。

Imports Microsoft.SqlServer.TransactSql.ScriptDom

Module Module1

    Sub Main()
        Dim fragment As TSqlFragment
        Dim parser As New TSql120Parser(True)
        Dim reader As System.IO.StreamReader
        Dim errors As IList(Of ParseError)

        reader = IO.File.OpenText("script.sql")

        fragment = parser.Parse(reader, errors)

        Dim foundIn As Boolean = False
        Dim foundView As Boolean = False
        Dim viewName As String = ""

        For Each tkn As TSqlParserToken In fragment.ScriptTokenStream
            If tkn.TokenType = TSqlTokenType.View Then
                foundView = True
            End If
            If tkn.TokenType = TSqlTokenType.In Then
                foundIn = True
            End If

            'Once you see a View, take everything until you see an As
            If foundView = True And tkn.TokenType = TSqlTokenType.As Then
                Console.WriteLine(viewName.Trim)
                viewName = ""
                foundView = False
            ElseIf foundView = True Then
                viewName += tkn.Text
            End If

            'Once you see an IN, collect the ASCII elements until a right parentheses is encountered.
            If tkn.TokenType = TSqlTokenType.AsciiStringLiteral And foundIn = True Then
                Console.WriteLine(tkn.Text)
            ElseIf tkn.TokenType = TSqlTokenType.RightParenthesis And foundIn = True Then
                'end of the IN condition
                foundIn = False
            End If
        Next

        Console.ReadKey()
    End Sub

End Module

输出这个...

【讨论】:

  • 抱歉回来晚了,是的,这让我走上了正轨。谢谢!
  • 太棒了! ScriptDom 库对我来说是新的,我可以在我做的一些事情中看到一些应用程序,所以这对我们俩来说都是一个很好的练习。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-12-27
  • 2012-12-21
  • 1970-01-01
  • 1970-01-01
  • 2017-04-24
  • 1970-01-01
  • 2023-03-10
  • 2019-04-22
相关资源
最近更新 更多