Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.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# SQL,所有列名都在括号中,C_C#_Sql Server_Tsql - Fatal编程技术网

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

C# SQL,所有列名都在括号中,C,c#,sql-server,tsql,C#,Sql Server,Tsql,我得到了一些用户在UI上输入的SQL语句: select * from [table] where [col1] is not null and col2 <> 0 我需要验证所有列名col1和col2是否都像col1一样放在括号中。如果任何列名不在本例中的括号内,则显示一些弹出消息,col2 在C中是否有某种方法可以进行这样的SQL验证?关于解析SQL,您可以使用Visual Studio附带的TSqlParser。此解析器接受从TSqlFragmentVisitor继承的访问者

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

select * from [table] where [col1] is not null and col2 <> 0
我需要验证所有列名col1和col2是否都像col1一样放在括号中。如果任何列名不在本例中的括号内,则显示一些弹出消息,col2


在C中是否有某种方法可以进行这样的SQL验证?

关于解析SQL,您可以使用Visual Studio附带的TSqlParser。此解析器接受从TSqlFragmentVisitor继承的访问者类,并重写ColumnReferenceExpression的访问方法


然而,我不确定解析用户在UI中输入的SQL是一个好主意。即使您在沙盒环境中运行SQL语句,其中用户仅具有读取权限,我希望您这样做,但它不是非常用户友好的。作为一名用户,我希望能够使用复选框或通过拖放来选择所需的列,而不必编写SQL查询。

当然,您只需要一个SQL解析器,但堆栈溢出不是一个好地方。为什么你甚至关心用户是否输入括号?所以你的用户可以用DELETE、DROP等语句编写查询?你认为从安全角度来看这是明智的吗?我得问问。你为什么关心它是否有一个[或否。您如何验证它是否是有效的SQL?另外,在UI中以文本形式键入查询的整个概念是SQL注入友好的。如果它们从UI中删除表或数据库会怎么样?Jaco,谢谢您的回答。我正在尝试使用statement.ScriptTokenStream列表验证每个令牌。但是如果我有where is isnumericcol3==1,我无法区分来自col3的isnumeric,因为对于这两种类型,类型都是identifier.Jaco,关于可用性,我完全同意你的看法。我添加了一个代码示例,更具体地针对你的问题hi@Alex,这段代码得到了结果,但是如果update语句带有连接,我如何获得表名呢?
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);
            }
        }
    }
}