SQL中,所有列名都在方括号中,C#

本文关键字:方括号 SQL | 更新日期: 2023-09-27 18:26:47

我得到一些SQL语句,用户在UI上输入:

select * from [table] where [col1] is not null and col2 <> 0

我需要验证所有列名(col1和col2)是否都在括号中(如col1)。如果任何列名不在括号中(在本例中为col2),则显示一些弹出消息。

有没有一些方法可以在C#中进行这样的SQL验证?

SQL中,所有列名都在方括号中,C#

关于解析SQL,您可以使用Visual Studio附带的TSqlParser库。这个解析器接受一个从TSqlFragmentVisitor继承的访问者类,并重写ColumnReferenceExpression的访问方法。
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Microsoft.SqlServer.TransactSql.ScriptDom;
namespace ConsoleApplication8
{
    public class QueryParser
    {
        public IEnumerable<string> Parse(string sqlSelect)
        {
            TSql100Parser parser = new TSql100Parser(false);
            TextReader rd = new StringReader(sqlSelect);
            IList<ParseError> errors;
            var columns = new List<string>();
            var fragments = parser.Parse(rd, out errors);
            var columnVisitor = new SQLVisitor();
            fragments.Accept(columnVisitor);
            columns = new List<string>(columnVisitor.Columns);
            return columns;
        }
    }

    internal class SQLVisitor : TSqlFragmentVisitor
    {
        private List<string> columns = new List<string>();
        private string GetNodeTokenText(TSqlFragment fragment) 
        { 
            StringBuilder tokenText = new StringBuilder(); 
            for (int counter = fragment.FirstTokenIndex; counter <= fragment.LastTokenIndex; counter++) 
            { 
                tokenText.Append(fragment.ScriptTokenStream[counter].Text); 
            }
            return tokenText.ToString(); 
        }

        public override void ExplicitVisit(ColumnReferenceExpression node)
        {
            columns.Add(GetNodeTokenText(node));
        }
        public IEnumerable<string>  Columns {
            get { return columns; }
        }
    } 
    public class Program
    {
        private static void Main(string[] args)
        {
            QueryParser queryParser = new QueryParser();
            var columns = queryParser.Parse("SELECT A,[B],C,[D],E FROM T  WHERE isnumeric(col3) = 1 Order by Id desc");
            foreach (var column in columns)
            {
                Console.WriteLine(column);
            }
        }
    }
}

然而,我不确定解析用户在UI中输入的SQL是否是个好主意。即使您在用户只有读取权限的沙盒环境中运行SQL语句(我确实希望您这样做),它对用户来说也不是很友好。作为一名用户,我更希望能够使用复选框或通过拖放来选择我想要的列,而不必编写SQL查询。