using CYQ.Data.Extension; using CYQ.Data.Table; using System; using System.Text.RegularExpressions; using System.Collections.Generic; using System.Data; namespace CYQ.Data.SQL { /// /// Sql 语句格式化类 (类似助手工具) /// internal class SqlFormat { /// /// Sql关键字处理 /// public static string Keyword(string name, DalType dalType) { if (!string.IsNullOrEmpty(name)) { name = name.Trim(); if (name.IndexOfAny(new char[] { ' ', '[', ']', '`', '"', '(', ')' }) == -1) { string pre = null; int i = name.LastIndexOf('.');// 增加跨库支持(demo.dbo.users) if (i > 0) { string[] items = name.Split('.'); pre = items[0]; name = items[items.Length - 1]; } switch (dalType) { case DalType.Access: return "[" + name + "]"; case DalType.MsSql: case DalType.Sybase: return (pre == null ? "" : pre + "..") + "[" + name + "]"; case DalType.MySql: return (pre == null ? "" : pre + ".") + "`" + name + "`"; case DalType.SQLite: case DalType.PostgreSQL: return "\"" + name + "\""; case DalType.Txt: case DalType.Xml: return NotKeyword(name); } } } return name; } /// /// 去除关键字符号 /// /// /// public static string NotKeyword(string name) { name = name.Trim(); if (name.IndexOfAny(new char[] { '(', ')' }) == -1 && name.Split(' ').Length == 1) { //string pre = string.Empty; int i = name.LastIndexOf('.');// 增加跨库支持(demo.dbo.users) if (i > 0) { // pre = name.Substring(0, i + 1); name = name.Substring(i + 1); } name = name.Trim('[', ']', '`', '"'); } return name; } /// /// Sql数据库兼容和Sql注入处理 /// public static string Compatible(object where, DalType dalType, bool isFilterInjection) { string text = GetIFieldSql(where); if (isFilterInjection) { text = SqlInjection.Filter(text, dalType); } text = SqlCompatible.Format(text, dalType); return RemoveWhereOneEqualsOne(text); } /// /// 移除"where 1=1" /// internal static string RemoveWhereOneEqualsOne(string sql) { try { sql = sql.Trim(); if (sql == "where 1=1") { return string.Empty; } if (sql.EndsWith(" and 1=1")) { return sql.Substring(0, sql.Length - 8); } int i = sql.IndexOf("where 1=1", StringComparison.OrdinalIgnoreCase); //do //{ if (i > 0) { if (i == sql.Length - 9)//以where 1=1 结束。 { sql = sql.Substring(0, sql.Length - 10); } else if (sql.Substring(i + 10, 8).ToLower() == "order by") { sql = sql.Remove(i, 10);//可能有多个。 } // i = sql.IndexOf("where 1=1", StringComparison.OrdinalIgnoreCase); } //} //while (i > 0); } catch { } return sql; } /// /// 创建补充1=2的SQL语句 /// /// 表名、或视图语句 /// internal static string BuildSqlWithWhereOneEqualsTow(string tableName) { tableName = tableName.Trim(); if (tableName[0] == '(' && tableName.IndexOf(')') > -1) { int end = tableName.LastIndexOf(')'); string sql = tableName.Substring(1, end - 1);//.Replace("\r\n", "\n").Replace('\n', ' '); 保留注释的换行。 string[] keys = new string[] { " where ", "\nwhere ", "\nwhere\r", "\nwhere\n" }; foreach (string key in keys) { if (sql.IndexOf(key, StringComparison.OrdinalIgnoreCase) > -1) { return Regex.Replace(sql, key, " where 1=2 and ", RegexOptions.IgnoreCase); } } //检测是否有group by keys = new string[] { " group by", "\ngroup by" }; foreach (string key in keys) { if (sql.IndexOf(key, StringComparison.OrdinalIgnoreCase) > -1) { string newKey = key.Replace("group", "where 1=2 group"); return Regex.Replace(sql, key, newKey, RegexOptions.IgnoreCase); } } return sql + " where 1=2"; } return string.Format("select * from {0} where 1=2", tableName); } /// /// Mysql Bit 类型不允许条件带引号 (字段='0' 不可以) /// /// /// /// internal static string FormatMySqlBit(string where, MDataColumn mdc) { if (where.Contains("'0'")) { foreach (MCellStruct item in mdc) { int groupID = DataType.GetGroup(item.SqlType); if (groupID == 1 || groupID == 3)//视图模式里取到的bit是bigint,所以数字一并处理 { if (where.IndexOf(item.ColumnName, StringComparison.OrdinalIgnoreCase) > -1) { string pattern = @"\s?" + item.ColumnName + @"\s*=\s*'0'"; where = Regex.Replace(where, pattern, " " + item.ColumnName + "=0", RegexOptions.IgnoreCase); } } } } return where; } internal static string FormatOracleDateTime(string where, MDataColumn mdc) { if (where.IndexOf(':') > -1 && where.IndexOfAny(new char[] { '>', '<', '-', '/' }) > -1)//判断是否存在日期的判断 { foreach (MCellStruct item in mdc) { if (DataType.GetGroup(item.SqlType) == 2 && where.IndexOf(item.ColumnName, StringComparison.OrdinalIgnoreCase) > -1) { string pattern = @"(\s?" + item.ColumnName + @"\s*[><]{1}[=]?\s*)('.{19,23}')"; Regex reg = new Regex(pattern, RegexOptions.IgnoreCase); if (reg.IsMatch(where)) { where = reg.Replace(where, delegate(Match match) { if (item.SqlType == SqlDbType.Timestamp) { return match.Groups[1].Value + "to_timestamp(" + match.Groups[2].Value + ",'yyyy-MM-dd HH24:MI:ss.ff')"; } else { return match.Groups[1].Value + "to_date(" + match.Groups[2].Value + ",'yyyy-mm-dd hh24:mi:ss')"; } }); } } } } return where; } internal static List GetTableNamesFromSql(string sql) { List nameList = new List(); //获取原始表名 string[] items = sql.Split(new char[] { ' ', ';', '(', ')', ',' }); if (items.Length == 1) { return nameList; }//单表名 if (items.Length > 3) // 总是包含空格的select * from xxx { bool isKeywork = false; foreach (string item in items) { if (!string.IsNullOrEmpty(item)) { string lowerItem = item.ToLower(); switch (lowerItem) { case "from": case "update": case "into": case "join": case "table": isKeywork = true; break; default: if (isKeywork) { if (item[0] == '(' || item.IndexOf('.') > -1) { isKeywork = false; } else { isKeywork = false; nameList.Add(NotKeyword(item)); } } break; } } } } return nameList; } #region IField处理 /// /// 静态的对IField接口处理 /// public static string GetIFieldSql(object whereObj) { if (whereObj is IField) { IField filed = whereObj as IField; string where = filed.Sql; filed.Sql = ""; return where; } return Convert.ToString(whereObj); } #endregion /// /// 将各数据库默认值格式化成标准值,将标准值还原成各数据库默认值 /// /// [0:转成标准值],[1:转成各数据库值],[2:转成各数据库值并补充字符串前后缀] /// 该列的值 /// public static string FormatDefaultValue(DalType dalType, object value, int flag, SqlDbType sqlDbType) { string defaultValue = Convert.ToString(value).Trim().TrimEnd('\n');//oracle会自带\n结尾 if (dalType != DalType.Access) { defaultValue = defaultValue.Replace("GenGUID()", string.Empty); } if (defaultValue.Length == 0) { return null; } int groupID = DataType.GetGroup(sqlDbType); if (flag == 0) { if (groupID == 2)//日期的标准值 { return SqlValue.GetDate; } else if (groupID == 4) { return SqlValue.Guid; } switch (dalType) { case DalType.MySql://用转\' \",所以不用替换。 defaultValue = defaultValue.Replace("\\\"", "\"").Replace("\\\'", "\'"); break; case DalType.Access: case DalType.SQLite: defaultValue = defaultValue.Replace("\"\"", "≮"); break; default: defaultValue = defaultValue.Replace("''", "≯"); break; } switch (defaultValue.ToLower().Trim('(', ')')) { case "newid": case "guid": case "sys_guid": case "genguid": case "uuid": return SqlValue.Guid; } } else { if (defaultValue == SqlValue.Guid) { switch (dalType) { case DalType.MsSql: case DalType.Oracle: case DalType.Sybase: return SqlCompatible.FormatGUID(defaultValue, dalType); default: return ""; } } } switch (dalType) { case DalType.Access: if (flag == 0) { if (defaultValue[0] == '"' && defaultValue[defaultValue.Length - 1] == '"') { defaultValue = defaultValue.Substring(1, defaultValue.Length - 2); } } else { defaultValue = defaultValue.Replace(SqlValue.GetDate, "Now()").Replace("\"", "\"\""); if (groupID == 0) { defaultValue = "\"" + defaultValue + "\""; } } break; case DalType.MsSql: case DalType.Sybase: if (flag == 0) { if (defaultValue.StartsWith("(") && defaultValue.EndsWith(")"))//避免 (newid()) 被去掉() { defaultValue = defaultValue.Substring(1, defaultValue.Length - 2); } defaultValue = defaultValue.Trim('N', '\'');//'(', ')', } else { defaultValue = defaultValue.Replace(SqlValue.GetDate, "getdate()").Replace("'", "''"); if (groupID == 0) { defaultValue = "(N'" + defaultValue + "')"; } } break; case DalType.Oracle: if (flag == 0) { defaultValue = defaultValue.Trim('\''); } else { defaultValue = defaultValue.Replace(SqlValue.GetDate, "sysdate").Replace("'", "''"); if (groupID == 0) { defaultValue = "'" + defaultValue + "'"; } } break; case DalType.MySql: if (flag == 0) { defaultValue = defaultValue.Replace("b'0", "0").Replace("b'1", "1").Trim(' ', '\''); } else { defaultValue = defaultValue.Replace(SqlValue.GetDate, "CURRENT_TIMESTAMP").Replace("'", "\\'").Replace("\"", "\\\""); if (groupID == 0) { defaultValue = "\"" + defaultValue + "\""; } } break; case DalType.SQLite: if (flag == 0) { defaultValue = defaultValue.Trim('"'); if (groupID > 0)//兼容一些不规范的写法。像数字型的加了引号 '0' { defaultValue = defaultValue.Trim('\''); } } else { defaultValue = defaultValue.Replace(SqlValue.GetDate, "CURRENT_TIMESTAMP").Replace("\"", "\"\""); if (groupID == 0) { defaultValue = "\"" + defaultValue + "\""; } } break; } if (flag == 0) { return defaultValue.Replace("≮", "\"").Replace("≯", "'"); } return defaultValue; } } }