Beispiel #1
0
        /// <summary>
        /// 复杂SQL解析,解析出所有的列
        /// </summary>
        /// <param name="functionData"></param>
        /// <returns></returns>
        public DbFunctionData GetFunctionData(DbFunctionData functionData)
        {
            dataUtility.con.Open();
            SelectStatementInfo selectStatement = new SelectStatementInfo(sqlInfo.sql);

            ParseSQL(ref selectStatement);
            functionData.fields           = GetFields(dataUtility, selectStatement);
            functionData.sqlVarParameters = new List <SqlVarParameter>();
            GetParameters(dataUtility, selectStatement, ref functionData.sqlVarParameters);
            dataUtility.con.Close();
            //转换为可执行的SQL
            functionData.sql = FormatSql(functionData.sql);
            return(functionData);
        }
Beispiel #2
0
        public void ParseSubSelect(ref SelectStatementInfo MainSelecteStatement)
        {
            string          subSelectPattern = @"\(\s*select\s+((?<open>\()|(?<-open>\))|[\s\S])*(?(open)(?!))\)";
            Regex           subSelectReg     = new Regex(subSelectPattern, RegexOptions.IgnoreCase);
            MatchCollection mac               = subSelectReg.Matches(MainSelecteStatement.sql);
            string          subSelectSql      = null;
            int             relative_position = 0;

            MainSelecteStatement.sqlWithOutSubSelect = MainSelecteStatement.sql;
            for (int i = 0; i < mac.Count; i++)
            {
                //去掉查到的子查询
                MainSelecteStatement.sqlWithOutSubSelect = MainSelecteStatement.sqlWithOutSubSelect.Remove(mac[i].Index + relative_position, mac[i].Length);
                relative_position -= mac[i].Length;
                //去掉两边的括号
                subSelectSql = mac[i].Value.Substring(1, mac[i].Value.Length - 2);
                SelectStatementInfo selectStatement = new SelectStatementInfo(subSelectSql);
                ParseSQL(ref selectStatement);
                MainSelecteStatement.selects.Add(selectStatement);
            }
        }
Beispiel #3
0
        /// <summary>
        /// 解析出SQL中的select,from,where子语句
        /// </summary>
        public void ParseSQL(ref SelectStatementInfo selectStatement)
        {
            //string sql="select count(*),id,name from (select * from users) right on a where id in(select id from users)";
            Regex selectReg    = new Regex(@"\s*select\s+", RegexOptions.IgnoreCase);
            Match selectMat    = selectReg.Match(selectStatement.sql);
            int   LeftBracket  = 0;
            int   RightBracket = 0;

            char[] sqlString = selectStatement.sql.ToCharArray();
            bool[] InBracket = new bool[sqlString.Length];
            for (int i = 0; i < sqlString.Length; i++)
            {
                if (sqlString[i] == '(')
                {
                    LeftBracket++;
                }
                else if (sqlString[i] == ')')
                {
                    RightBracket++;
                }
                if (LeftBracket == RightBracket)
                {
                    InBracket[i] = false;
                }
                else
                {
                    InBracket[i] = true;
                }
            }
            Regex           fromReg = new Regex(@"\s+from\s+", RegexOptions.IgnoreCase);
            MatchCollection fromMac = fromReg.Matches(selectStatement.sql);
            Match           fromMat = null;

            for (int i = 0; i < fromMac.Count; i++)
            {
                if (!InBracket[fromMac[i].Index])
                {
                    fromMat = fromMac[i];
                    break;
                }
            }
            Regex           whereReg = new Regex(@"\s+where\s+", RegexOptions.IgnoreCase);
            MatchCollection whereMac = whereReg.Matches(selectStatement.sql);
            Match           whereMat = null;

            for (int i = 0; i < whereMac.Count; i++)
            {
                if (!InBracket[whereMac[i].Index])
                {
                    whereMat = whereMac[i];
                    break;
                }
            }
            Regex otherReg = new Regex(@"\s+(group\s+by|having|order\s+by|with|limit)\s+");

            selectStatement.selectClause = selectStatement.sql.Substring(selectMat.Index + selectMat.Length, fromMat.Index - selectMat.Index - selectMat.Length);
            //如果where不存在
            if (whereMat == null)
            {
                selectStatement.fromClause  = selectStatement.sql.Substring(fromMat.Index + fromMat.Length);
                selectStatement.whereClause = null;

                Match otherMat = otherReg.Match(selectStatement.fromClause);
                if (otherMat.Success)
                {
                    selectStatement.fromClause = selectStatement.fromClause.Substring(0, otherMat.Index);
                }
                selectStatement.selects = new List <SelectStatementInfo>();
            }
            //如果where存在
            else
            {
                selectStatement.fromClause  = selectStatement.sql.Substring(fromMat.Index + fromMat.Length, whereMat.Index - fromMat.Index - fromMat.Length);
                selectStatement.whereClause = selectStatement.sql.Substring(whereMat.Index + whereMat.Length);
                Match otherMat = otherReg.Match(selectStatement.whereClause);
                if (otherMat.Success)
                {
                    selectStatement.whereClause = selectStatement.whereClause.Substring(0, otherMat.Index);
                }
                selectStatement.selects = new List <SelectStatementInfo>();
                ParseSubSelect(ref selectStatement);
            }
        }
Beispiel #4
0
        public List <DB.Coding.Field> GetFields(DB.Coding.DataUtility dataUtility, SelectStatementInfo selectStatement)
        {
            List <DB.Coding.Field> fields = new List <DB.Coding.Field>();
            string selectFiledsSql        = string.Format("select {0} from {1} where 1>2", selectStatement.selectClause, selectStatement.fromClause);

            System.Data.Common.DbCommand    cmd    = dataUtility.GetDbCommand(FormatSql(selectFiledsSql), dataUtility.con);
            System.Data.DataTable           dt     = new System.Data.DataTable();
            System.Data.Common.DbDataReader reader = cmd.ExecuteReader();
            dt = reader.GetSchemaTable();
            reader.Read();
            Regex nameReg = new Regex(@"^[_0-9a-zA-Z]+$");

            for (int i = 0; i < dt.Rows.Count; i++)
            {
                DB.Coding.Field field = new DB.Coding.Field();
                field.name            = dt.Rows[i]["BaseColumnName"].ToString();
                field.structFieldName = dt.Rows[i]["ColumnName"].ToString();
                //查看名称是否合法,不合法则重命名.
                if (!nameReg.IsMatch(field.name))
                {
                    field.name = "_column" + i.ToString();
                }
                if (!nameReg.IsMatch(field.structFieldName))
                {
                    field.structFieldName = "_column" + i.ToString();
                }
                field.allowNull  = Convert.ToBoolean(dt.Rows[i]["AllowDBNull"]);
                field.csTypeLink = dataUtility.csTypeDic[dt.Rows[i]["DataType"].ToString().Split('.')[1]];
                if (dataUtility.dbType == DB.DBType.Sqlite)
                {
                    field.sqlType = dt.Rows[i]["DataTypeName"].ToString();
                }
                else
                {
                    field.sqlType = reader.GetDataTypeName(i);
                }
                field.isId      = Convert.ToBoolean(dt.Rows[i]["IsKey"]);
                field.length    = Convert.ToInt32(dt.Rows[i]["ColumnSize"]);
                field.localType = dt.Rows[i]["DataType"].ToString();
                field.isId      = Convert.ToBoolean(dt.Rows[i]["IsKey"]);
                field.position  = Convert.ToInt32(dt.Rows[i]["ColumnOrdinal"]);
                field.dbType    = dataUtility.GetDbType(Convert.ToInt32(dt.Rows[i]["ProviderType"]));
                //field.hasDefault = dt.Rows[i]["DefaultValue"] != null;
                //field.defautlValue = field.hasDefault ? dt.Rows[i]["DefaultValue"].ToString() : null;
                //如果没有相对应的数据库类型
                if (!string.IsNullOrEmpty(field.sqlType))
                {
                    if (dataUtility.typeDic.ContainsKey(field.sqlType.ToLower()))
                    {
                        field.simpleType = dataUtility.typeDic[field.sqlType.ToLower()].simpleType;
                    }
                    else
                    {
                        switch (field.localType)
                        {
                        case "System.Int16": field.simpleType = "Number"; break;

                        case "System.Int32": field.simpleType = "Number"; break;

                        case "System.Int64": field.simpleType = "Number"; break;

                        case "System.UInt16": field.simpleType = "Number"; break;

                        case "System.UInt32": field.simpleType = "Number"; break;

                        case "System.UInt64": field.simpleType = "Number"; break;

                        case "System.Byte": field.simpleType = "Number"; break;

                        case "System.SByte": field.simpleType = "Number"; break;

                        case "System.Single": field.simpleType = "Number"; break;

                        case "System.Decimal": field.simpleType = "Number"; break;

                        case "System.Double": field.simpleType = "Number"; break;

                        case "System.TimeSpan": field.simpleType = "Time"; break;

                        case "System.DateTime:": field.simpleType = "Time"; break;

                        default: field.simpleType = field.simpleType = "String"; break;
                        }
                    }
                }
                else
                {
                    switch (field.localType)
                    {
                    case "System.Int16": field.simpleType = "Number"; break;

                    case "System.Int32": field.simpleType = "Number"; break;

                    case "System.Int64": field.simpleType = "Number"; break;

                    case "System.UInt16": field.simpleType = "Number"; break;

                    case "System.UInt32": field.simpleType = "Number"; break;

                    case "System.UInt64": field.simpleType = "Number"; break;

                    case "System.Byte": field.simpleType = "Number"; break;

                    case "System.SByte": field.simpleType = "Number"; break;

                    case "System.Single": field.simpleType = "Number"; break;

                    case "System.Decimal": field.simpleType = "Number"; break;

                    case "System.Double": field.simpleType = "Number"; break;

                    case "System.TimeSpan": field.simpleType = "Time"; break;

                    case "System.DateTime:": field.simpleType = "Time"; break;

                    default: field.simpleType = field.simpleType = "String"; break;
                    }
                }
                fields.Add(field);
            }
            reader.Close();
            return(fields);
        }
Beispiel #5
0
        public List <SqlVarParameter> GetParameters(DB.Coding.DataUtility dataUtility, SelectStatementInfo selectStatement, ref List <SqlVarParameter> allSqlVarParameters)
        {
            List <SqlVarParameter> sqlVarParameters = ParseVarName(selectStatement.sqlWithOutSubSelect);

            if (sqlVarParameters.Count > 0)
            {
                string sqlParametersSelect = "select ";
                for (int i = 0; i < sqlVarParameters.Count; i++)
                {
                    if (i != 0)
                    {
                        sqlParametersSelect += ",";
                    }
                    sqlParametersSelect += sqlVarParameters[i].fullName;
                }
                sqlParametersSelect += " from " + selectStatement.fromClause + " where 1>2 ";


                Regex fromReg = new Regex(@"\s+from\s+", RegexOptions.IgnoreCase);

                System.Data.Common.DbCommand    cmd    = dataUtility.GetDbCommand(FormatSql(sqlParametersSelect), dataUtility.con);
                System.Data.DataTable           dt     = new System.Data.DataTable();
                System.Data.Common.DbDataReader reader = cmd.ExecuteReader();
                dt = reader.GetSchemaTable();
                reader.Read();
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    SqlVarParameter parameter = sqlVarParameters[i];

                    DB.Coding.Field field = new DB.Coding.Field();
                    field.name            = dt.Rows[i]["BaseColumnName"].ToString();
                    field.structFieldName = dt.Rows[i]["ColumnName"].ToString();
                    field.allowNull       = Convert.ToBoolean(dt.Rows[i]["AllowDBNull"]);
                    field.csTypeLink      = dataUtility.csTypeDic[dt.Rows[i]["DataType"].ToString().Split('.')[1]];
                    if (dataUtility.dbType == DB.DBType.Sqlite)
                    {
                        field.sqlType = dt.Rows[i]["DataTypeName"].ToString();
                    }
                    else
                    {
                        field.sqlType = reader.GetDataTypeName(i);
                    }
                    field.isId      = Convert.ToBoolean(dt.Rows[i]["IsKey"]);
                    field.length    = Convert.ToInt32(dt.Rows[i]["ColumnSize"]);
                    field.localType = dt.Rows[i]["DataType"].ToString();
                    field.isId      = Convert.ToBoolean(dt.Rows[i]["IsKey"]);
                    field.position  = Convert.ToInt32(dt.Rows[i]["ColumnOrdinal"]);
                    field.dbType    = dataUtility.GetDbType(Convert.ToInt32(dt.Rows[i]["ProviderType"]));
                    //field.hasDefault = dt.Rows[i]["DefaultValue"] != null;
                    //field.defautlValue = field.hasDefault ? dt.Rows[i]["DefaultValue"].ToString() : null;
                    if (!string.IsNullOrEmpty(field.sqlType))
                    {
                        if (dataUtility.typeDic.ContainsKey(field.sqlType.ToLower()))
                        {
                            field.simpleType = dataUtility.typeDic[field.sqlType.ToLower()].simpleType;
                        }
                        else
                        {
                            field.simpleType = "String";
                        }
                    }
                    else
                    {
                        field.simpleType = "";
                    }
                    parameter.field = field;
                    allSqlVarParameters.Add(parameter);
                }
                reader.Close();
            }
            //分析子查询里的参数
            for (int i = 0; i < selectStatement.selects.Count; i++)
            {
                GetParameters(dataUtility, selectStatement.selects[i], ref allSqlVarParameters);
            }
            return(sqlVarParameters);
        }