C# } if(identifierTokenTypes.Contains(queryTokens[j].TokenType)) { (某人清楚地); GetQuoteIdentifier(queryTokens[j],sb); 而(j+2tableName.T

C# } if(identifierTokenTypes.Contains(queryTokens[j].TokenType)) { (某人清楚地); GetQuoteIdentifier(queryTokens[j],sb); 而(j+2tableName.T,c#,sql,C#,Sql,} if(identifierTokenTypes.Contains(queryTokens[j].TokenType)) { (某人清楚地); GetQuoteIdentifier(queryTokens[j],sb); 而(j+2tableName.ToList(); } } 私有静态无效GetQuoteIdentifier(TSqlParserToken令牌,StringBuilder sb) { 开关(token.TokenType) { 案例TSqlTokenType。标识符: sb.

} if(identifierTokenTypes.Contains(queryTokens[j].TokenType)) { (某人清楚地); GetQuoteIdentifier(queryTokens[j],sb); 而(j+2tableName.ToList(); } } 私有静态无效GetQuoteIdentifier(TSqlParserToken令牌,StringBuilder sb) { 开关(token.TokenType) { 案例TSqlTokenType。标识符: sb.Append('[').Append(token.Text).Append(']'); 打破 案例TSqlTokenType.QuoteIdentifier: 案例TSqlTokenType.Dot: sb.Append(token.Text); 打破 默认值:抛出新ArgumentException(“错误:令牌的预期令牌类型应为TSqlTokenType.Dot、TSqlTokenType.Identifier或TSqlTokenType.QuoteIdentifier”); } } }
为什么要这样做?有任何特定的RDBMS/SQL方言吗?如果TSQL您可以查看
TSql100Parser
除非有一个稍微复杂的正则表达式,我想不出任何东西可以做到这一点。我很好奇现在是否有一些API或查询。我支持初学者的问题…你为什么要这样做?逻辑是你必须找到关键字后面出现的所有单词,如FROM JOIN等,然后列出它们。这看起来很有趣,但不起作用。更糟糕的是,它只是偶尔起作用。我是说重要的公园,很明显逗号分隔不是问题。我确信我是唯一一个对数据库进行查询的人(它是本地数据库),但大多数时候我只收到空响应。您是否在同一个会话中一起执行它们?是的。我有一个数据库,有大约百条记录,当我在r.Sample\u id=s.Sample\u id上调用Result r JOIN Sample s中的SELECT TOP 5*时,它总是工作的,当我在r.Sample\u id=s.Sample上调用Result r JOIN Sample s中的SELECT*时,它几乎从不工作_id@user436730你说得对,对不起,我修好了。问题是在这种情况下,sql_语句不像“从中选择前1个*(选择%'我改为使用vwQueryStats,因为%I修改了原始代码段,忘记了更改上次执行的查询的条件。我尝试了它,现在可以工作,不适用于省略架构名称的完全限定表名…需要一些调整才能使其适用于这种情况我发布了一个答案,修改了代码以支持此代码块用于处理什么情况?if(queryTokens[j+2]。TokenType==TSqlTokenType.Dot){if(queryTokens[j-1]。TokenType==TSqlTokenType.Dot)getQuoteIdentifier(queryTokens[j+1],sb);j++;}我正在为此编写单元测试,但找不到进入此块的方法。@MatthewVines已经两年了,我真的不记得了,但我想到的是带有模式的完全限定名的标记,例如“select*from[mydb].[myschema].[mytable]”感谢您的关注。在经历了许多不同的场景之后,我能够将这组表达式剥离为if(queryTokens[j+2]。TokenType==TSqlTokenType.Dot){j++;},而没有任何功能损失。
SELECT * FROM Table t JOIN OtherTable ON t.id=OtherTable.t_id
Table, OtherTable
SELECT Field1 As "OtherTable.Field1",
       Field2 As "Table.Field2"
FROM Table t JOIN OtherTable ON t.id=OtherTable.t_id
   SELECT Field1, Field2 
   FROM Table t JOIN OtherTable ON t.id=OtherTable.t_id

  ;WITH vwQueryStats AS(
     SELECT 
      COALESCE(OBJECT_NAME(s2.objectid),'Ad-Hoc') AS ProcName
      ,execution_count
      ,s2.objectid
      ,(
         SELECT TOP 1 
            SUBSTRING(s2.TEXT,statement_start_offset / 2+1 
            ,( ( CASE WHEN statement_end_offset = -1
                THEN (LEN(CONVERT(NVARCHAR(MAX),s2.TEXT)) * 2)
                ELSE statement_end_offset END)- statement_start_offset) / 2+1)) AS sql_statement
            ,last_execution_time
         FROM sys.dm_exec_query_stats AS s1
         CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS s2
    )
    SELECT TOP 1 * 
    INTO #lastQueryStats
    FROM vwQueryStats x
    WHERE sql_statement NOT like 'WITH vwQueryStats AS%'
    ORDER BY last_execution_time DESC

    SELECT
    TABLE_NAME
    FROM #lastQueryStats, INFORMATION_SCHEMA.TABLES tab 
    WHERE CHARINDEX( tab.TABLE_NAME, sql_statement) > 0


    DROP TABLE #lastQueryStats 
 Table
 OtherTable
DECLARE @tableNames VARCHAR(MAX) 

SELECT @tableNames = COALESCE(@tableNames + ', ', '') + TABLE_NAME
FROM   #lastQueryStats, INFORMATION_SCHEMA.TABLES tab 
WHERE  CHARINDEX( tab.TABLE_NAME, sql_statement) > 0

SELECT @tableNames 
private List<string> GetTableNamesFromQueryString(string query)
{
    IList<ParseError> errors = new List<ParseError>();
    IList<TSqlParserToken> queryTokens;
    List<string> output = new List<string>(16);
    StringBuilder sb = new StringBuilder(128);
    TSql120Parser parser = new TSql120Parser(true);
    TSqlTokenType[] fromTokenTypes = new TSqlTokenType[2]
        {
            TSqlTokenType.From,
            TSqlTokenType.Join
        };
    TSqlTokenType[] identifierTokenTypes = new TSqlTokenType[2]
        {
            TSqlTokenType.Identifier,
            TSqlTokenType.QuotedIdentifier
        };

    using (System.IO.TextReader tReader = new System.IO.StringReader(query))
    {
        queryTokens = parser.GetTokenStream(tReader, out errors);
        if (errors.Count > 0) { return errors.Select(e=>"Error: " + e.Number + " Line: " + e.Line + " Column: " + e.Column + " Offset: " + e.Offset + " Message: " + e.Message).ToList(); }

        for (int i = 0; i < queryTokens.Count; i++)
        {
            if(fromTokenTypes.Contains(queryTokens[i].TokenType))
            {
                for (int j = i + 1; j < queryTokens.Count; j++)
                {
                    if (queryTokens[j].TokenType == TSqlTokenType.WhiteSpace) { continue; }
                    else if (identifierTokenTypes.Contains(queryTokens[j].TokenType))
                    {
                        sb.Clear();

                        GetQuotedIdentifier(queryTokens[j], sb);            //Change Identifiers to QuotedIdentifier (text only)

                        while (j + 2 < queryTokens.Count && queryTokens[j + 1].TokenType == TSqlTokenType.Dot && identifierTokenTypes.Contains(queryTokens[j + 2].TokenType))
                        {
                            sb.Append(queryTokens[j + 1].Text);
                            GetQuotedIdentifier(queryTokens[j + 2], sb);    //Change Identifiers to QuotedIdentifier (text only)

                            j += 2;
                        }

                        output.Add(sb.ToString());
                        break;              //exit the loop
                    }
                    else { break; }             //exit the loop if token is not a FROM, a JOIN, or white space.
                }

            }
        }

        return output.Distinct().OrderBy(tableName => tableName).ToList();
    }
}

private void GetQuotedIdentifier(TSqlParserToken token, StringBuilder sb)
{
    switch(token.TokenType)
    {
        case TSqlTokenType.Identifier: sb.Append('[').Append(token.Text).Append(']'); return;
        case TSqlTokenType.QuotedIdentifier: sb.Append(token.Text); return;
        default: throw new ArgumentException("Error: expected TokenType of token should be TSqlTokenType.Identifier or TSqlTokenType.QuotedIdentifier");
    }
}
public class Parser
{
    public static List<string> GetTableNamesFromQueryString(string query)
    {
        var output = new List<string>();
        var sb = new StringBuilder();
        var parser = new TSql120Parser(true);

        var fromTokenTypes = new[]
        {
            TSqlTokenType.From,
            TSqlTokenType.Join
        };

        var identifierTokenTypes = new[]
        {
            TSqlTokenType.Identifier,
            TSqlTokenType.QuotedIdentifier
        };

        using (System.IO.TextReader tReader = new System.IO.StringReader(query))
        {
            IList<ParseError> errors;
            var queryTokens = parser.GetTokenStream(tReader, out errors);
            if (errors.Any())
            {
                return errors
                    .Select(e => string.Format("Error: {0}; Line: {1}; Column: {2}; Offset: {3};  Message: {4};", e.Number, e.Line, e.Column, e.Offset, e.Message))
                    .ToList();
            }

            for (var i = 0; i < queryTokens.Count; i++)
            {
                if (fromTokenTypes.Contains(queryTokens[i].TokenType))
                {
                    for (var j = i + 1; j < queryTokens.Count; j++)
                    {
                        if (queryTokens[j].TokenType == TSqlTokenType.WhiteSpace)
                        {
                            continue;
                        }

                        if (identifierTokenTypes.Contains(queryTokens[j].TokenType))
                        {
                            sb.Clear();
                            GetQuotedIdentifier(queryTokens[j], sb);

                            while (j + 2 < queryTokens.Count 
                                && queryTokens[j + 1].TokenType == TSqlTokenType.Dot 
                                && (queryTokens[j + 2].TokenType == TSqlTokenType.Dot || identifierTokenTypes.Contains(queryTokens[j + 2].TokenType)))
                            {
                                sb.Append(queryTokens[j + 1].Text);

                                if (queryTokens[j + 2].TokenType == TSqlTokenType.Dot)
                                {
                                    if (queryTokens[j - 1].TokenType == TSqlTokenType.Dot) 
                                        GetQuotedIdentifier(queryTokens[j + 1], sb);

                                    j++;

                                }
                                else
                                {
                                    GetQuotedIdentifier(queryTokens[j + 2], sb);
                                    j += 2;
                                }
                            }

                            output.Add(sb.ToString());
                        }
                        break;
                    }
                }
            }

            return output.Distinct().OrderBy(tableName => tableName).ToList();
        }
    }

    private static void GetQuotedIdentifier(TSqlParserToken token, StringBuilder sb)
    {
        switch (token.TokenType)
        {
            case TSqlTokenType.Identifier: 
                sb.Append('[').Append(token.Text).Append(']'); 
                break;
            case TSqlTokenType.QuotedIdentifier:
            case TSqlTokenType.Dot: 
                sb.Append(token.Text); 
                break;

            default: throw new ArgumentException("Error: expected TokenType of token should be TSqlTokenType.Dot, TSqlTokenType.Identifier, or TSqlTokenType.QuotedIdentifier");
        }
    }
}