SQL解析器: - 获取表名和列名

时间:2015-07-20 21:23:26

标签: c#

我正在使用SQL解析器来解析SQL查询并获取表和字段的名称。

我从sqlparser.com下载了演示项目,但未能编译它。 项目中也有参考图书馆。

演示的来源是: -

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

using gudusoft.gsqlparser;
using gudusoft.gsqlparser.Units;


namespace getTableColumn
{

    class getTableColumn
    {


        static List<string> tablelist, columnlist, databaselist, schemalist, functionlist, triggerlist, sequencelist;
        static StringBuilder tcList;
        static Boolean showStructure = false, showList = true, showLocation = false, showEffect = false;

        /**
         * This is a sample callback function used by SQL parser to determine
         * relationship between table and column like this SQL:
         * *
         * SELECT
         * Quantity,b.Time,c.Description
         * FROM
         * (SELECT ID,Time FROM bTab) b
         * INNER JOIN aTab a on a.ID=b.ID
         * INNER JOIN cTab c on a.ID=c.ID
         * 
         * column: Quantity will be linked to table: cTab with the help of this
         * callback function.
         * otherwise, column: Quantity will be linked to table: aTab by default
         * 
         */
        private static bool metadataTableColumn(Object sender, string pServer, string pDatabase, string pSchema, string pTable, string pColumn)
        {
            string[,] columns = new string[3, 5] { 
                                    { "s1", "d1","dbo", "t1", "c1" }, 
                                    { "s2", "d2","dbo", "t2", "c2" }, 
                                    { "s3", "d3","dbo", "t3", "c3" } };

            bool bServer = false, bDatabase = false, bSchema = false, bTable = false, bColumn = false;
            for (int i = 0; i < 3; i++)
            {
                if (pServer == "") bServer = true;
                else bServer = pServer.Equals(columns[i, 0], StringComparison.OrdinalIgnoreCase);
                if (!bServer) continue;

                if (pDatabase == "") bDatabase = true;
                else bDatabase = pDatabase.Equals(columns[i, 1], StringComparison.OrdinalIgnoreCase);
                if (!bDatabase) continue;

                if (pSchema == "") bSchema = true;
                else bSchema = pSchema.Equals(columns[i, 2], StringComparison.OrdinalIgnoreCase);
                if (!bSchema) continue;

                bTable = pTable.Equals(columns[i, 3], StringComparison.OrdinalIgnoreCase);
                if (!bTable) continue;

                bColumn = pColumn.Equals(columns[i, 4], StringComparison.OrdinalIgnoreCase);
                if (!bColumn) continue;

                break;
            }
            return bColumn;
        }

        static void sortAndRemoveDup(List<string> pList)
        {
            pList.Sort();
            Int32 index = 0;
            while (index < pList.Count - 1)
            {
                if (pList[index] == pList[index + 1])
                    pList.RemoveAt(index);
                else
                    index++;
            }
        }

        static void Main(string[] args)
        {
            string filename = "", dbvendor = "";


            if (args.Length == 0)
            {
                Console.WriteLine("Usage: {0} scriptfile [/d dbvendor] [/v]", Environment.GetCommandLineArgs()[0]);
                Console.WriteLine("\t/d \t\t set database vendor");
                Console.WriteLine("\tdbvendor \t oracle, mssql, mysql or db2");
                Console.WriteLine("\t/v \t\t show detailed information");
                return;
            }

            Array array = Array.CreateInstance(typeof(string), args.Length);

            for (int i = 0; i < array.Length; i++)
            {
                array.SetValue(args[i], i);
            }

            showLocation = Array.IndexOf(array, "/v") != -1;
            showEffect = Array.IndexOf(array, "/v") != -1;
            showStructure = Array.IndexOf(array, "/v") != -1;

            filename = args[0];

            int index = Array.IndexOf(array, "/d");

            if (index != -1 && args.Length > index + 1)
            {
                dbvendor = args[index + 1];
            }

            TDbVendor db = TDbVendor.DbVOracle;


            if (dbvendor.Equals("mssql"))
            {
                db = TDbVendor.DbVMssql;
            }
            else if (dbvendor.Equals("db2"))
            {
                db = TDbVendor.DbVDB2;
            }
            else if (dbvendor.Equals("mysql"))
            {
                db = TDbVendor.DbVMysql;
            }



            //if (args.Length == 2)
            //{
            //    bSortColumn = args[1].Equals("-s", StringComparison.OrdinalIgnoreCase);
            //}



            TGSqlParser sqlparser = new TGSqlParser(db);
            sqlparser.Sqlfilename = filename;

            // please use your own function to check table column relation using meta
            // information from database

          //  sqlparser.OnMetaDatabaseTableColumn += metadataTableColumn;

            int ret = sqlparser.Parse();

            if (ret != 0)
            {
                Console.WriteLine(sqlparser.ErrorMessages);
                return;
            }

            tablelist = new List<string>();
            columnlist = new List<string>();
            databaselist = new List<string>();
            schemalist = new List<string>();
            functionlist = new List<string>();
            triggerlist = new List<string>();
            sequencelist = new List<string>();
            tcList = new StringBuilder();


            for (int i = 0; i < sqlparser.SqlStatements.Count(); i++)
            {
                TCustomSqlStatement sql = sqlparser.SqlStatements[i];
                analyzeStmt(sql, 0);
            }

            if (showStructure)
            {
                Console.WriteLine(tcList.ToString());
            }

            showList = true;

            if (showList)
            {
                sortAndRemoveDup(tablelist);
                sortAndRemoveDup(columnlist);
                sortAndRemoveDup(databaselist);
                sortAndRemoveDup(schemalist);
                sortAndRemoveDup(functionlist);
                sortAndRemoveDup(triggerlist);
                sortAndRemoveDup(sequencelist);

                Console.WriteLine("Tables:");
                Console.WriteLine(new StringBuilder(string.Join("\r\n", tablelist.ToArray())).ToString());
                Console.WriteLine("Fields:");
                Console.WriteLine(new StringBuilder(string.Join("\r\n", columnlist.ToArray())).ToString());
                if (databaselist.Count > 0)
                {
                    Console.WriteLine("database:");
                    Console.WriteLine(new StringBuilder(string.Join("\r\n", databaselist.ToArray())).ToString());
                }
                if (schemalist.Count > 0)
                {
                    Console.WriteLine("schema:");
                    Console.WriteLine(new StringBuilder(string.Join("\r\n", schemalist.ToArray())).ToString());
                }
                if (functionlist.Count > 0)
                {
                    Console.WriteLine("Functions:");
                    Console.WriteLine(new StringBuilder(string.Join("\r\n", functionlist.ToArray())).ToString());
                }
                if (triggerlist.Count > 0)
                {
                    Console.WriteLine("Triggers:");
                    Console.WriteLine(new StringBuilder(string.Join("\r\n", triggerlist.ToArray())).ToString());
                }
                if (sequencelist.Count > 0)
                {
                    Console.WriteLine("Sequences:");
                    Console.WriteLine(new StringBuilder(string.Join("\r\n", sequencelist.ToArray())).ToString());
                }

            }

            //Console.Read();

        }

        static void analyzeStmt(TCustomSqlStatement stmt, int pNest)
        {
            tcList.AppendLine("");
            tcList.AppendLine(string.Format("{0}{1}", " ".PadLeft(pNest, ' '), stmt.SqlStatementType));

            string tn = "", tneffect = "";
            for (int k = 0; k < stmt.Tables.Count(); k++)
            {
                if (stmt.Tables[k].TableType == TLzTableType.lttSubquery)
                {
                    tn = "(subquery, alias:" + stmt.Tables[k].TableAlias + ")";
                }
                else
                {
                    tn = stmt.Tables[k].TableFullname;
                    if (stmt.Tables[k].isLinkTable)
                    {
                        tn = tn + "(" + stmt.Tables[k].linkedTable.TableFullname + ")";
                    }
                    else if (stmt.Tables[k].isCTE)
                    {
                        tn = tn + "(CTE)";
                    }

                }
                if (!((stmt.Tables[k].TableType == TLzTableType.lttSubquery) || (stmt.Tables[k].isCTE)))
                {
                    tablelist.Add(tn);
                }

                if (showEffect)
                {
                    tneffect = string.Format("{0}({1})", tn, stmt.Tables[k].effectType);
                }
                else
                {
                    tneffect = string.Format("{0}", tn);
                }
                tcList.AppendLine(string.Format("{0}{1}", " ".PadLeft(pNest + 1, ' '), tneffect));


                for (int m = 0; m < stmt.Tables[k].linkedColumns.Count(); m++)
                {
                    String columnInfo = "";
                    if (showLocation)
                    {
                        columnInfo = string.Format("{0}({1})", stmt.Tables[k].linkedColumns[m].fieldAttrName, stmt.Tables[k].linkedColumns[m].Location);
                    }
                    else
                    {
                        columnInfo = string.Format("{0}", stmt.Tables[k].linkedColumns[m].fieldAttrName);
                    }
                    tcList.AppendLine(string.Format("{0}{1}", " ".PadLeft(pNest + 2, ' '), columnInfo));

                    if (!((stmt.Tables[k].TableType == TLzTableType.lttSubquery) || (stmt.Tables[k].isCTE)))
                    {
                        if (stmt.Tables[k].isLinkTable)
                        { //mssql, deleted, inserted table
                            columnlist.Add(stmt.Tables[k].linkedTable.TableFullname + '.' + stmt.Tables[k].linkedColumns[m].fieldAttrName);
                        }
                        else
                            columnlist.Add(tn + '.' + stmt.Tables[k].linkedColumns[m].fieldAttrName);
                    }
                }
            }

            if (stmt.orphanColumns.Count() > 0)
            {
                tcList.AppendLine(string.Format("{0}{1}", " ".PadLeft(pNest + 1, ' '), " orphan columns:"));
                for (int k = 0; k < stmt.orphanColumns.Count(); k++)
                {
                    tcList.AppendLine(string.Format("{0}{1}", " ".PadLeft(pNest + 2, ' '), stmt.orphanColumns[k].AsText));
                    columnlist.Add("missing." + stmt.orphanColumns[k].AsText);
                }
            }

            if (stmt.DatabaseTokens.Count() > 0)
            {
                for (int k = 0; k < stmt.DatabaseTokens.Count(); k++)
                {
                    databaselist.Add(stmt.DatabaseTokens[k].AsText);
                }
            }

            if (stmt.SchemaTokens.Count() > 0)
            {
                for (int k = 0; k < stmt.SchemaTokens.Count(); k++)
                {
                    schemalist.Add(stmt.SchemaTokens[k].AsText);
                }
            }

            if (stmt.FunctionTokens.Count() > 0)
            {
                for (int k = 0; k < stmt.FunctionTokens.Count(); k++)
                {
                    if (stmt.FunctionTokens[k].ParentToken != null)
                    {
                        functionlist.Add(stmt.FunctionTokens[k].ParentToken.AsText + "." + stmt.FunctionTokens[k].AsText);
                    }
                    else
                    {
                        functionlist.Add(stmt.FunctionTokens[k].AsText);
                    }
                }
            }

            if (stmt.TriggerTokens.Count() > 0)
            {
                for (int k = 0; k < stmt.TriggerTokens.Count(); k++)
                {
                    if (stmt.TriggerTokens[k].ParentToken != null)
                    {
                        triggerlist.Add(stmt.TriggerTokens[k].ParentToken.AsText + "." + stmt.TriggerTokens[k].AsText);
                    }
                    else
                    {
                        triggerlist.Add(stmt.TriggerTokens[k].AsText);
                    }
                }
            }

            if (stmt.SequenceTokens.Count() > 0)
            {
                for (int k = 0; k < stmt.SequenceTokens.Count(); k++)
                {
                    sequencelist.Add(stmt.SequenceTokens[k].AsText);
                }
            }


            for (int j = 0; j < stmt.ChildNodes.Count(); j++)
            {
                if (stmt.ChildNodes[j] is TCustomSqlStatement)
                {
                    analyzeStmt(stmt.ChildNodes[j] as TCustomSqlStatement, pNest + 1);
                }
            }
        }


        static string getTokenLocation(TSourceToken st)
        {
            if ((st.Location == TLzOwnerLocation.elfieldbyattr)
                || (st.Location == TLzOwnerLocation.elfieldbyexpr)
                )
            {
                return "columnResult/select list";
            }
            else if (st.Location == TLzOwnerLocation.elWhere)
            {
                return "where clause";
            }
            else if (st.Location == TLzOwnerLocation.elHaving)
            {
                return "having clause";
            }
            else if (st.Location == TLzOwnerLocation.elgroupby)
            {
                return "group by clause";
            }
            else if (st.Location == TLzOwnerLocation.elorderby)
            {
                return "order by clause";
            }
            else if (st.Location == TLzOwnerLocation.eltableFuncArg)
            {
                return "from clause";
            }
            else if (st.Location == TLzOwnerLocation.eljoinCondition)
            {
                return "join condition";
            }
            else
            {
                return st.Location.ToString();
            }

        }

    }
}

错误堆栈如下:

Error   91  'gudusoft.gsqlparser.TCustomSqlStatement' does not contain a definition for 'orphanColumns' and no extension method 'orphanColumns' accepting a first argument of type 'gudusoft.gsqlparser.TCustomSqlStatement' could be found (are you missing a using directive or an assembly reference?)   C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  292 22  getTableColumn
Error   92  'gudusoft.gsqlparser.TCustomSqlStatement' does not contain a definition for 'orphanColumns' and no extension method 'orphanColumns' accepting a first argument of type 'gudusoft.gsqlparser.TCustomSqlStatement' could be found (are you missing a using directive or an assembly reference?)   C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  295 42  getTableColumn
Error   93  'gudusoft.gsqlparser.TCustomSqlStatement' does not contain a definition for 'orphanColumns' and no extension method 'orphanColumns' accepting a first argument of type 'gudusoft.gsqlparser.TCustomSqlStatement' could be found (are you missing a using directive or an assembly reference?)   C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  297 97  getTableColumn
Error   94  'gudusoft.gsqlparser.TCustomSqlStatement' does not contain a definition for 'orphanColumns' and no extension method 'orphanColumns' accepting a first argument of type 'gudusoft.gsqlparser.TCustomSqlStatement' could be found (are you missing a using directive or an assembly reference?)   C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  298 52  getTableColumn
Error   76  'gudusoft.gsqlparser.TGSqlParser' does not contain a definition for 'OnMetaDatabaseTableColumn' and no extension method 'OnMetaDatabaseTableColumn' accepting a first argument of type 'gudusoft.gsqlparser.TGSqlParser' could be found (are you missing a using directive or an assembly reference?)   C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  149 23  getTableColumn
Error   95  'gudusoft.gsqlparser.TLzOwnerLocation' does not contain a definition for 'eljoinCondition'  C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  391 54  getTableColumn
Error   81  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'effectType' and no extension method 'effectType' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?)   C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  259 77  getTableColumn
Error   79  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'isCTE' and no extension method 'isCTE' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  246 46  getTableColumn
Error   80  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'isCTE' and no extension method 'isCTE' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  252 97  getTableColumn
Error   86  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'isCTE' and no extension method 'isCTE' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  281 101 getTableColumn
Error   77  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'isLinkTable' and no extension method 'isLinkTable' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  243 40  getTableColumn
Error   87  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'isLinkTable' and no extension method 'isLinkTable' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  283 43  getTableColumn
Error   82  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'linkedColumns' and no extension method 'linkedColumns' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  268 52  getTableColumn
Error   83  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'linkedColumns' and no extension method 'linkedColumns' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  273 79  getTableColumn
Error   84  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'linkedColumns' and no extension method 'linkedColumns' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  273 126 getTableColumn
Error   85  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'linkedColumns' and no extension method 'linkedColumns' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  277 74  getTableColumn
Error   89  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'linkedColumns' and no extension method 'linkedColumns' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  284 107 getTableColumn
Error   90  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'linkedColumns' and no extension method 'linkedColumns' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  287 67  getTableColumn
Error   78  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'linkedTable' and no extension method 'linkedTable' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  245 54  getTableColumn
Error   88  'gudusoft.gsqlparser.TLzTable' does not contain a definition for 'linkedTable' and no extension method 'linkedTable' accepting a first argument of type 'gudusoft.gsqlparser.TLzTable' could be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\gsqlparser_dotnet_trial_2_6_4 (3)\democollections\getTableColumn\getTableColumn.cs  284 58  getTableColumn

1 个答案:

答案 0 :(得分:1)

回答问题所在。只需在TokenizeQuery类中调用exec方法即可。 表名和列名将存储在列表中。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using gudusoft.gsqlparser;
using gudusoft.gsqlparser.Units;
namespace Custom.Data {

    class TokenizeQuery {

        public static List < String > TableNames = new List < String > ();
        public static List < String > ColumnNames = new List < String > ();
        // public static String inputSql = "SELECT * FROM ABC";
        public void exec(String query) {
            TableNames.Clear();
            ColumnNames.Clear();
            getTableColumn _new = new getTableColumn();
            _new.GetTableColumnName(query);
        }

        public void print() {
            Console.WriteLine("**************************************************************");
            Console.Write("TABLES\n\n");
            TableNames.ForEach(i => Console.Write("{0}\n", i));
            Console.Write("COLUMNS\n\n");
            ColumnNames.ForEach(i => Console.Write("{0}\n", i));
            Console.WriteLine("**************************************************************");
        }


        #
        region tableInfo
        class tableInfo {
            public TCustomSqlStatement stmt;
            public TSourceToken database, schema, table, tableAlias;

            public string getDatabaseName() {
                if (database == null) {
                    return "";
                } else {
                    return database.AsText;
                }
            }

            public string getSchemaName() {
                if (schema == null) {
                    return "";
                } else {
                    return schema.AsText;
                }
            }

            public string getTableName() {
                if (table == null) {
                    return "";
                } else {
                    return table.AsText;
                }
            }

            public string getTableAliasName() {
                if (tableAlias == null) {
                    return "";
                } else {
                    return tableAlias.AsText;
                }
            }

            public tableInfo(TCustomSqlStatement s) {
                stmt = s;
            }
        }

        #
        endregion

        # region columnInfo
        class columnInfo {
            public tableInfo table;
            public TSourceToken column;
            public string columnAlias;
            //public int lineNo, columnNo;
            public TLzOwnerLocation location;
            public TLzExpression columnExpr;
            public columnInfo(tableInfo t) {
                table = new tableInfo(t.stmt);
                table.database = t.database;
                table.schema = t.schema;
                table.table = t.table;
                table.tableAlias = t.tableAlias;
            }
        }

        #
        endregion

        class getTableColumn {

            static List < columnInfo > columnInfos = null;

            static bool bSortColumn = false;

            /**
             * This is a sample callback function used by SQL parser to determine
             * relationship between table and column like this SQL:
             * *
             * SELECT
             * Quantity,b.Time,c.Description
             * FROM
             * (SELECT ID,Time FROM bTab) b
             * INNER JOIN aTab a on a.ID=b.ID
             * INNER JOIN cTab c on a.ID=c.ID
             * 
             * column: Quantity will be linked to table: cTab with the help of this
             * callback function.
             * otherwise, column: Quantity will be linked to table: aTab by default
             * 
             */
            private static bool metadataTableColumn(Object sender, string pSchema, string pTable, string pColumn) {
                string[, ] columns = new string[3, 3] {
                    {
                        "dbo", "subselect2table1", "s2t1a1"
                    }, {
                        "dbo", "subselect3table1", "Quantity2"
                    }, {
                        "dbo", "subselect3table2", "s3t1a1"
                    }
                };

                bool bSchema = false, bTable = false, bColumn = false;
                for (int i = 0; i < 3; i++) {
                    if (pSchema == "") bSchema = true;
                    else bSchema = pSchema.Equals(columns[i, 0], StringComparison.OrdinalIgnoreCase);
                    if (!bSchema) continue;

                    bTable = pTable.Equals(columns[i, 1], StringComparison.OrdinalIgnoreCase);
                    if (!bTable) continue;

                    bColumn = pColumn.Equals(columns[i, 2], StringComparison.OrdinalIgnoreCase);
                    if (!bColumn) continue;

                    break;
                }
                return bColumn;
            }

            public void GetTableColumnName(String inputSql) {



                columnInfos = new List < columnInfo > ();

                TGSqlParser sqlparser = new TGSqlParser(TDbVendor.DbVOracle); //DbVMssql
                sqlparser.SqlText.Text = inputSql;

                // please use your own function to check table column relation using meta
                // information from database

                //sqlparser.OnMetaDatabaseTableColumn += metadataTableColumn;

                int ret = sqlparser.Parse();

                if (ret != 0) {
                    Console.WriteLine(sqlparser.ErrorMessages);
                    return;
                }



                for (int i = 0; i < sqlparser.SqlStatements.Count(); i++) {
                    TCustomSqlStatement sql = sqlparser.SqlStatements[i];
                    printTableTokensInStmt(sql, 0);

                    for (int j = 0; j < sql.ChildNodes.Count(); j++) {
                        if (sql.ChildNodes[j] is TCustomSqlStatement) {
                            tablesInStmt(sql.ChildNodes[j] as TCustomSqlStatement, 0);
                        }
                    }

                }

                if (bSortColumn) {
                    //Console.WriteLine(System.Environment.NewLine + "print columns in the same order they appear in sql statement");
                    columnInfos.Sort(delegate(columnInfo a, columnInfo b) {
                        int xdiff = a.column.XPosition - b.column.XPosition;
                        if (xdiff != 0) return xdiff;
                        return a.column.YPosition - b.column.YPosition;
                    });

                    printColumnInfos();
                }



            }

            static void printColumnInfos() {

                int columnOrder = 1;
                //Console.WriteLine("{0,-15}{1,-25}{2,-25}{3,-15}\n{4,-20}{5,-20}{6,-40}", "pos", "column", "table", "t-alias", "schema", "DB","Loc");
                Console.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7}", "columnOrder", "location", "ColumnName", "TableName", "TableAlias", "Schema", "DatabaseName", "Notes");
                foreach(columnInfo c in columnInfos) {

                    TSourceToken st = c.column;
                    String notes = "";

                    if (st.Location == TLzOwnerLocation.elWhere) {
                        notes = whereclause(c.table.stmt, st);
                    } else if (st.Location == TLzOwnerLocation.elHaving) {
                        notes = havingclause((TSelectSqlStatement) c.table.stmt, st);
                    } else if (st.Location == TLzOwnerLocation.eljoinitemcondition) {
                        notes = joincondition((TSelectSqlStatement) c.table.stmt, st);
                    }

                    //  Console.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7}", String.Format("[{0,3},{1,3}]", c.column.XPosition, c.column.YPosition), c.column.AsText, c.table.getTableName(), c.table.getTableAliasName(), c.table.getSchemaName(), c.table.getDatabaseName(), getTokenLocation(c.column).Trim());
                    Console.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7}", columnOrder, getTokenLocation(c.column), c.column.AsText, c.table.getTableName(), c.table.getTableAliasName(), c.table.getSchemaName(), c.table.getDatabaseName(), notes);
                    columnOrder++;
                }
            }

            static void tablesInStmt(TCustomSqlStatement stmt, int level) {

                printTableTokensInStmt(stmt, level);

                for (int j = 0; j < stmt.ChildNodes.Count(); j++) {
                    if (stmt.ChildNodes[j] is TCustomSqlStatement) {
                        tablesInStmt(stmt.ChildNodes[j] as TCustomSqlStatement, level + 1);
                    }
                }

            }

            static void printTableTokensInStmt(TCustomSqlStatement stmt, int level) {
                tableInfo tableInfo = new tableInfo(stmt);

                TSourceTokenList tokenList = stmt.TableTokens;
                if (!bSortColumn) {
                    String typeinfo = stmt.SqlStatementType.ToString();
                    if (stmt is TLzPlsql_Package) {
                        TLzPlsql_Package package = (TLzPlsql_Package) stmt;
                        typeinfo += '(' + package._package_name.AsText + ')';
                    } else if (stmt is TLzPlsql_SubProgram) {
                        TLzPlsql_SubProgram procedure = (TLzPlsql_SubProgram) stmt;
                        typeinfo += '(' + procedure._procedure_name.AsText + ')';
                    } else if (stmt is TLzPlsql_Trigger) {
                        TLzPlsql_Trigger trigger = (TLzPlsql_Trigger) stmt;
                        typeinfo += '(' + trigger._ndTriggername.AsText + ')';
                    }
                    Console.WriteLine(new String(' ', level) + "tables in {0}: {1}  adfafsasfa", typeinfo, tokenList.Count());

                }



                TSourceToken st = null;
                string tablestr = null;
                string tablealias = null;

                for (int i = 0; i < tokenList.Count(); i++) {
                    st = tokenList[i];
                    tableInfo.table = st;
                    tablestr = st.AsText;
                    if (st.RelatedToken != null) {
                        tablealias = "alias: " + st.RelatedToken.AsText;
                        tableInfo.tableAlias = st.RelatedToken;
                    }
                    if (st.ParentToken != null) {
                        //schema
                        tablestr = st.ParentToken.AsText + "." + tablestr;
                        tableInfo.schema = st.ParentToken;

                        if (st.ParentToken.ParentToken != null) {
                            //database
                            tablestr = st.ParentToken.ParentToken.AsText + "." + tablestr;
                            tableInfo.database = st.ParentToken.ParentToken;
                        }
                    }
                    if (!bSortColumn) {
                        TableNames.Add(tablestr);
                        Console.WriteLine(new String(' ', level + 1) + "TABLE NAME" + tablestr + getTokenPosition(st) + " " + tablealias);
                    }
                    printColumnsInTableToken(stmt, st, level + 2, tableInfo);
                }
            }

            static void printColumnsInTableToken(TCustomSqlStatement stmt, TSourceToken st, int level, tableInfo tableInfo) {

                if (st.RelatedToken != null) {
                    // declared table alias token
                    TSourceToken rt = st.RelatedToken;
                    TSourceToken rrt = null;
                    for (int i = 0; i < rt.RelatedTokens.Count(); i++) {
                        rrt = rt.RelatedTokens[i];
                        if (rrt.ChildToken != null) {
                            columnInfo columnInfo = new columnInfo(tableInfo);
                            columnInfo.column = rrt.ChildToken;
                            columnInfos.Add(columnInfo);

                            if (!bSortColumn) {
                                ColumnNames.Add(rrt.ChildToken.AsText);
                                Console.WriteLine(new String(' ', level + 1) + "IDHAR HU" + rrt.ChildToken.AsText + getTokenPosition(rrt.ChildToken) + "," + getTokenLocation(rrt.ChildToken));
                            }
                        }
                    }
                }

                TSourceToken rtt = null;
                for (int i = 0; i < st.RelatedTokens.Count(); i++) {
                    // reference table token
                    rtt = st.RelatedTokens[i];
                    if (rtt.DBObjType == TDBObjType.ttObjField) {
                        // get all field tokens link with table token (those token not linked by syntax like tablename.fieldname)
                        // but like this : select f from t

                        columnInfo columnInfo = new columnInfo(tableInfo);
                        columnInfo.column = rtt;
                        columnInfos.Add(columnInfo);

                        if (!bSortColumn)
                            Console.WriteLine(new String(' ', level + 1) + rtt.AsText + getTokenPosition(rtt) + getColumnTokenIsDetermined(rtt) + "," + getTokenLocation(rtt));
                    }
                    if (rtt.ChildToken != null) {
                        columnInfo columnInfo = new columnInfo(tableInfo);
                        columnInfo.column = rtt.ChildToken;
                        columnInfos.Add(columnInfo);

                        if (!bSortColumn)
                            Console.WriteLine(new String(' ', level + 1) + rtt.ChildToken.AsText + getTokenPosition(rtt.ChildToken) + getColumnTokenIsDetermined(rtt.ChildToken) + "," + getTokenLocation(rtt.ChildToken));
                    }
                }
            }

            static string getColumnTokenIsDetermined(TSourceToken st) {
                if ((st.DBObjType == TDBObjType.ttObjField)) {
                    return " <guessed> ";
                } else {
                    return "";
                }
            }
            static string getTokenPosition(TSourceToken st) {
                return "(" + st.XPosition + "," + st.YPosition + ")";
            }

            static string getTokenLocation(TSourceToken st) {
                if ((st.Location == TLzOwnerLocation.elfieldbyattr) || (st.Location == TLzOwnerLocation.elfieldbyexpr)) {
                    return "columnResult/select list";
                } else if (st.Location == TLzOwnerLocation.elWhere) {
                    return "where clause";
                } else if (st.Location == TLzOwnerLocation.elHaving) {
                    return "having clause";
                } else if (st.Location == TLzOwnerLocation.elgroupby) {
                    return "group by clause";
                } else if (st.Location == TLzOwnerLocation.elorderby) {
                    return "order by clause";
                } else if (st.Location == TLzOwnerLocation.eltableFuncArg) {
                    return "from clause";
                } else if (st.Location == TLzOwnerLocation.eljoinitemcondition) {
                    return "join condition";
                } else {
                    return st.Location.ToString();
                }

            }

            static string whereclause(TCustomSqlStatement stmt, TSourceToken st) {
                string ret = "";
                if (stmt.WhereClause == null) {
                    return ret;
                }

                ret = stmt.WhereClause.AsText;

                return ret;
            }

            static string havingclause(TSelectSqlStatement stmt, TSourceToken st) {
                string ret = "";
                if (stmt.HavingClause == null) {
                    return ret;
                }

                ret = stmt.HavingClause.AsText;

                return ret;
            }

            static string joincondition(TSelectSqlStatement stmt, TSourceToken st) {
                string ret = "";
                if (stmt.JoinTables.Count() == 0) {
                    return ret;
                }

                TLzJoin join = stmt.JoinTables[0];
                if (join.JoinItems.Count() == 0) {
                    return ret;
                }

                foreach(TLzJoinItem joinitem in join.JoinItems) {
                    for (int k = joinitem.JoinQual.StartToken.posinlist; k <= joinitem.JoinQual.EndToken.posinlist; k++) {
                        if (st.posinlist == k) {
                            ret = joinitem.JoinQual.AsText;
                            break;
                        }
                    }
                }


                return ret;
            }


        }

    }
}