Skip to content

Commit

Permalink
修复Expression批量插入转换Oracle数据对应sql错误bug;修复Oracle仓储分页方法错误bug;新增sql注入扩展方法;…
Browse files Browse the repository at this point in the history
…新增OracleDynamicParameters实现Dapper的IDynamicParameters接口;优化Page方法,精简仓储代码;
  • Loading branch information
zqlovejyc committed Jul 13, 2019
1 parent 5010706 commit c307933
Show file tree
Hide file tree
Showing 15 changed files with 257 additions and 1,085 deletions.
14 changes: 7 additions & 7 deletions SQLBuilder.UnitTest/SelectTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ public void Test_Page_01()
.AndWhere(o => o.Name == "")
.OrWhere(o => o.Subject == "")
.Page(3, 2, "Id", "select * from student");
Assert.AreEqual(@"SELECT COUNT(1) AS Records FROM (select * from student) AS T;SELECT * FROM (select * from student) AS X ORDER BY X.Id LIMIT 3 OFFSET 3;", builder.Sql);
Assert.AreEqual(@"DROP TEMPORARY TABLE IF EXISTS $TEMPORARY;CREATE TEMPORARY TABLE $TEMPORARY SELECT * FROM (select * from student) AS T;SELECT COUNT(1) AS Total FROM $TEMPORARY;SELECT * FROM $TEMPORARY AS X ORDER BY Id LIMIT 3 OFFSET 3;DROP TABLE $TEMPORARY;", builder.Sql);
Assert.AreEqual(0, builder.Parameters.Count);
}

Expand All @@ -1022,7 +1022,7 @@ public void Test_Page_02()
.AndWhere(o => o.Name == "")
.OrWhere(o => o.Subject == "")
.Page(3, 2, "Id");
Assert.AreEqual(@"SELECT COUNT(1) AS Records FROM (SELECT * FROM `student` AS A WHERE A.Score IS NOT NULL AND A.Name = ?Param0 OR A.Subject = ?Param1) AS T;SELECT * FROM (SELECT * FROM `student` AS A WHERE A.Score IS NOT NULL AND A.Name = ?Param0 OR A.Subject = ?Param1) AS X ORDER BY X.Id LIMIT 3 OFFSET 3;", builder.Sql);
Assert.AreEqual(@"DROP TEMPORARY TABLE IF EXISTS $TEMPORARY;CREATE TEMPORARY TABLE $TEMPORARY SELECT * FROM (SELECT * FROM `student` AS A WHERE A.Score IS NOT NULL AND A.Name = ?Param0 OR A.Subject = ?Param1) AS T;SELECT COUNT(1) AS Total FROM $TEMPORARY;SELECT * FROM $TEMPORARY AS X ORDER BY Id LIMIT 3 OFFSET 3;DROP TABLE $TEMPORARY;", builder.Sql);
Assert.AreEqual(2, builder.Parameters.Count);
}

Expand All @@ -1035,7 +1035,7 @@ public void Test_Page_03()
var builder = SqlBuilder.Select<UserInfo>(u => u.Id)
.Where(u => u.Name == "b" && (u.Id > 2 && u.Name != null && (u.Email == "11" || u.Email == "22" || u.Email == "ee")))
.Page(10, 1, "Id");
Assert.AreEqual(@"SELECT COUNT(1) AS Records FROM (SELECT A.Id FROM [Base_UserInfo] AS A WHERE A.Name = @Param0 AND (A.Id > @Param1 AND A.Name IS NOT NULL AND (A.Email = @Param2 OR A.Email = @Param3 OR A.Email = @Param4))) AS T;SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY X.Id) AS RowNumber,X.* FROM (SELECT A.Id FROM [Base_UserInfo] AS A WHERE A.Name = @Param0 AND (A.Id > @Param1 AND A.Name IS NOT NULL AND (A.Email = @Param2 OR A.Email = @Param3 OR A.Email = @Param4))) AS X) AS T WHERE RowNumber BETWEEN 1 AND 10;", builder.Sql);
Assert.AreEqual(@"IF OBJECT_ID(N'TEMPDB..#TEMPORARY') IS NOT NULL DROP TABLE #TEMPORARY;SELECT * INTO #TEMPORARY FROM (SELECT A.Id FROM [Base_UserInfo] AS A WHERE A.Name = @Param0 AND (A.Id > @Param1 AND A.Name IS NOT NULL AND (A.Email = @Param2 OR A.Email = @Param3 OR A.Email = @Param4))) AS T;SELECT COUNT(1) AS Total FROM #TEMPORARY;SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber, * FROM #TEMPORARY) AS N WHERE RowNumber BETWEEN 1 AND 10;DROP TABLE #TEMPORARY;", builder.Sql);
Assert.AreEqual(5, builder.Parameters.Count);
}

Expand All @@ -1048,7 +1048,7 @@ public void Test_Page_04()
var builder = SqlBuilder.Select<UserInfo>(u => u.Id)
.Where(u => u.Name == "b" && (u.Id > 2 && u.Name != null && (u.Email == "11" || u.Email == "22" || u.Email == "ee")))
.PageByWith(10, 1, "Id");
Assert.AreEqual(@"WITH T AS (SELECT A.Id FROM [Base_UserInfo] AS A WHERE A.Name = @Param0 AND (A.Id > @Param1 AND A.Name IS NOT NULL AND (A.Email = @Param2 OR A.Email = @Param3 OR A.Email = @Param4))) SELECT COUNT(1) AS Records FROM T;WITH X AS (SELECT A.Id FROM [Base_UserInfo] AS A WHERE A.Name = @Param0 AND (A.Id > @Param1 AND A.Name IS NOT NULL AND (A.Email = @Param2 OR A.Email = @Param3 OR A.Email = @Param4))),T AS (SELECT ROW_NUMBER() OVER (ORDER BY X.Id) AS RowNumber,X.* FROM X) SELECT * FROM T WHERE RowNumber BETWEEN 1 AND 10;", builder.Sql);
Assert.AreEqual(@"IF OBJECT_ID(N'TEMPDB..#TEMPORARY') IS NOT NULL DROP TABLE #TEMPORARY;WITH T AS (SELECT A.Id FROM [Base_UserInfo] AS A WHERE A.Name = @Param0 AND (A.Id > @Param1 AND A.Name IS NOT NULL AND (A.Email = @Param2 OR A.Email = @Param3 OR A.Email = @Param4))) SELECT * INTO #TEMPORARY FROM T;SELECT COUNT(1) AS Total FROM #TEMPORARY;WITH R AS (SELECT ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber,* FROM #TEMPORARY) SELECT * FROM R WHERE RowNumber BETWEEN 1 AND 10;DROP TABLE #TEMPORARY;", builder.Sql);
Assert.AreEqual(5, builder.Parameters.Count);
}

Expand All @@ -1059,7 +1059,7 @@ public void Test_Page_04()
public void Test_Page_05()
{
var builder = SqlBuilder.Select<UserInfo>().PageByWith(10, 1, "Id", "WITH T AS (SELECT * FROM Base_UserInfo)");
Assert.AreEqual(@"WITH T AS (SELECT * FROM Base_UserInfo)SELECT COUNT(1) AS Records FROM T;WITH T AS (SELECT * FROM Base_UserInfo),R AS (SELECT ROW_NUMBER() OVER (ORDER BY T.Id) AS RowNumber,T.* FROM T) SELECT * FROM R WHERE RowNumber BETWEEN 1 AND 10;", builder.Sql);
Assert.AreEqual(@"IF OBJECT_ID(N'TEMPDB..#TEMPORARY') IS NOT NULL DROP TABLE #TEMPORARY;WITH T AS (SELECT * FROM Base_UserInfo) SELECT * INTO #TEMPORARY FROM T;SELECT COUNT(1) AS Total FROM #TEMPORARY;WITH R AS (SELECT ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber,* FROM #TEMPORARY) SELECT * FROM R WHERE RowNumber BETWEEN 1 AND 10;DROP TABLE #TEMPORARY;", builder.Sql);
Assert.AreEqual(0, builder.Parameters.Count);
}

Expand All @@ -1070,7 +1070,7 @@ public void Test_Page_05()
public void Test_Page_06()
{
var builder = SqlBuilder.Select<UserInfo>().Page(10, 1, "Id", "WITH T AS (SELECT * FROM Base_UserInfo)");
Assert.AreEqual(@"WITH T AS (SELECT * FROM Base_UserInfo)SELECT COUNT(1) AS Records FROM T;WITH T AS (SELECT * FROM Base_UserInfo),R AS (SELECT ROW_NUMBER() OVER (ORDER BY T.Id) AS RowNumber,T.* FROM T) SELECT * FROM R WHERE RowNumber BETWEEN 1 AND 10;", builder.Sql);
Assert.AreEqual(@"IF OBJECT_ID(N'TEMPDB..#TEMPORARY') IS NOT NULL DROP TABLE #TEMPORARY;WITH T AS (SELECT * FROM Base_UserInfo) SELECT * INTO #TEMPORARY FROM T;SELECT COUNT(1) AS Total FROM #TEMPORARY;WITH R AS (SELECT ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber,* FROM #TEMPORARY) SELECT * FROM R WHERE RowNumber BETWEEN 1 AND 10;DROP TABLE #TEMPORARY;", builder.Sql);
Assert.AreEqual(0, builder.Parameters.Count);
}

Expand All @@ -1081,7 +1081,7 @@ public void Test_Page_06()
public void Test_Page_07()
{
var builder = SqlBuilder.Select<UserInfo>(DatabaseType: DatabaseType.MySQL).PageByWith(10, 1, "Id", "WITH T AS (SELECT * FROM `Base_UserInfo`)");
Assert.AreEqual(@"WITH T AS (SELECT * FROM `Base_UserInfo`)SELECT COUNT(1) AS Records FROM T;WITH T AS (SELECT * FROM `Base_UserInfo`)SELECT * FROM T ORDER BY T.Id LIMIT 10 OFFSET 0;", builder.Sql);
Assert.AreEqual(@"WITH T AS (SELECT * FROM `Base_UserInfo`) SELECT COUNT(1) AS Total FROM T;WITH T AS (SELECT * FROM `Base_UserInfo`) SELECT * FROM T ORDER BY Id LIMIT 10 OFFSET 0;", builder.Sql);
Assert.AreEqual(0, builder.Parameters.Count);
}
#endregion
Expand Down
18 changes: 11 additions & 7 deletions SQLBuilder/Expression/ListInitExpressionResolve.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,20 @@ public override SqlPack Insert(ListInitExpression expression, SqlPack sqlPack)
{
var fields = new List<string>();
var array = expression.ToObject() as IEnumerable<object>;
foreach (var item in array)
for (var i = 0; i < array.Count(); i++)
{
sqlPack.Sql.Append("(");
var properties = item?.GetType().GetProperties();
if (sqlPack.DatabaseType != DatabaseType.Oracle)
sqlPack.Sql.Append("(");
if (i > 0 && sqlPack.DatabaseType == DatabaseType.Oracle)
sqlPack.Sql.Append(" UNION ALL SELECT ");
var properties = array.ElementAt(i)?.GetType().GetProperties();
foreach (var p in properties)
{
var type = p.DeclaringType.ToString().Contains("AnonymousType") ? sqlPack.DefaultType : p.DeclaringType;
(string columnName, bool isInsert, bool isUpdate) = sqlPack.GetColumnInfo(type, p);
if (isInsert)
{
var value = p.GetValue(item, null);
var value = p.GetValue(array.ElementAt(i), null);
if (value != null || (sqlPack.IsEnableNullValue && value == null))
{
sqlPack.AddDbParameter(value);
Expand All @@ -61,13 +64,14 @@ public override SqlPack Insert(ListInitExpression expression, SqlPack sqlPack)
if (sqlPack[sqlPack.Length - 1] == ',')
{
sqlPack.Sql.Remove(sqlPack.Length - 1, 1);
sqlPack.Sql.Append("),");
if (sqlPack.DatabaseType != DatabaseType.Oracle)
sqlPack.Sql.Append("),");
else
sqlPack.Sql.Append(" FROM DUAL");
}
}
if (sqlPack.Sql[sqlPack.Sql.Length - 1] == ',')
{
sqlPack.Sql.Remove(sqlPack.Sql.Length - 1, 1);
}
sqlPack.Sql = new StringBuilder(string.Format(sqlPack.ToString(), string.Join(",", fields).TrimEnd(',')));
return sqlPack;
}
Expand Down
24 changes: 11 additions & 13 deletions SQLBuilder/Expression/MemberExpressionResolve.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,28 +41,25 @@ public override SqlPack Insert(MemberExpression expression, SqlPack sqlPack)
var fields = new List<string>();
var obj = expression.ToObject();
if (obj.GetType().IsArray)
{
objectArray.AddRange(obj as object[]);
}
else if (obj.GetType().Name == "List`1")
{
objectArray.AddRange(obj as IEnumerable<object>);
}
else
{
objectArray.Add(obj);
}
foreach (var item in objectArray)
for (var i = 0; i < objectArray.Count; i++)
{
sqlPack.Sql.Append("(");
var properties = item?.GetType().GetProperties();
if (sqlPack.DatabaseType != DatabaseType.Oracle)
sqlPack.Sql.Append("(");
if (i > 0 && sqlPack.DatabaseType == DatabaseType.Oracle)
sqlPack.Sql.Append(" UNION ALL SELECT ");
var properties = objectArray[i]?.GetType().GetProperties();
foreach (var p in properties)
{
var type = p.DeclaringType.ToString().Contains("AnonymousType") ? sqlPack.DefaultType : p.DeclaringType;
(string columnName, bool isInsert, bool isUpdate) = sqlPack.GetColumnInfo(type, p);
if (isInsert)
{
var value = p.GetValue(item, null);
var value = p.GetValue(objectArray[i], null);
if (value != null || (sqlPack.IsEnableNullValue && value == null))
{
sqlPack.AddDbParameter(value);
Expand All @@ -74,13 +71,14 @@ public override SqlPack Insert(MemberExpression expression, SqlPack sqlPack)
if (sqlPack[sqlPack.Length - 1] == ',')
{
sqlPack.Sql.Remove(sqlPack.Length - 1, 1);
sqlPack.Sql.Append("),");
if (sqlPack.DatabaseType != DatabaseType.Oracle)
sqlPack.Sql.Append("),");
else
sqlPack.Sql.Append(" FROM DUAL");
}
}
if (sqlPack[sqlPack.Length - 1] == ',')
{
sqlPack.Sql.Remove(sqlPack.Length - 1, 1);
}
sqlPack.Sql = new StringBuilder(string.Format(sqlPack.ToString(), string.Join(",", fields).TrimEnd(',')));
return sqlPack;
}
Expand Down
10 changes: 6 additions & 4 deletions SQLBuilder/Expression/MemberInitExpressionResolve.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public class MemberInitExpressionResolve : BaseSqlBuilder<MemberInitExpression>
/// <returns>SqlPack</returns>
public override SqlPack Insert(MemberInitExpression expression, SqlPack sqlPack)
{
sqlPack.Sql.Append("(");
if (sqlPack.DatabaseType != DatabaseType.Oracle)
sqlPack.Sql.Append("(");
var fields = new List<string>();
foreach (MemberAssignment m in expression.Bindings)
{
Expand All @@ -56,7 +57,10 @@ public override SqlPack Insert(MemberInitExpression expression, SqlPack sqlPack)
if (sqlPack[sqlPack.Length - 1] == ',')
{
sqlPack.Sql.Remove(sqlPack.Length - 1, 1);
sqlPack.Sql.Append(")");
if (sqlPack.DatabaseType != DatabaseType.Oracle)
sqlPack.Sql.Append(")");
else
sqlPack.Sql.Append(" FROM DUAL");
}
sqlPack.Sql = new StringBuilder(string.Format(sqlPack.ToString(), string.Join(",", fields).TrimEnd(',')));
return sqlPack;
Expand Down Expand Up @@ -86,9 +90,7 @@ public override SqlPack Update(MemberInitExpression expression, SqlPack sqlPack)
}
}
if (sqlPack[sqlPack.Length - 1] == ',')
{
sqlPack.Sql.Remove(sqlPack.Length - 1, 1);
}
return sqlPack;
}
#endregion
Expand Down
38 changes: 20 additions & 18 deletions SQLBuilder/Expression/MethodCallExpressionResolve.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ private static void Like(MethodCallExpression expression, SqlPack sqlPack)
case DatabaseType.Oracle:
case DatabaseType.SQLite:
sqlPack += " LIKE '%' || ";
break;
break;
default:
break;
}
SqlBuilderProvider.Where(expression.Arguments[1], sqlPack);
SqlBuilderProvider.Where(expression.Arguments[1], sqlPack);
switch (sqlPack.DatabaseType)
{
case DatabaseType.SQLServer:
Expand All @@ -116,7 +116,7 @@ private static void Like(MethodCallExpression expression, SqlPack sqlPack)
case DatabaseType.Oracle:
case DatabaseType.SQLite:
sqlPack += " || '%'";
break;
break;
default:
break;
}
Expand Down Expand Up @@ -235,7 +235,7 @@ private static void NotLike(MethodCallExpression expression, SqlPack sqlPack)
default:
break;
}
SqlBuilderProvider.Where(expression.Arguments[1], sqlPack);
SqlBuilderProvider.Where(expression.Arguments[1], sqlPack);
switch (sqlPack.DatabaseType)
{
case DatabaseType.SQLServer:
Expand Down Expand Up @@ -350,7 +350,7 @@ private static void ToUpper(MethodCallExpression expression, SqlPack sqlPack)
sqlPack += "UPPER(";
SqlBuilderProvider.Where(expression.Object, sqlPack);
sqlPack += ")";
}
}
}

/// <summary>
Expand All @@ -365,7 +365,7 @@ private static void ToLower(MethodCallExpression expression, SqlPack sqlPack)
sqlPack += "LOWER(";
SqlBuilderProvider.Where(expression.Object, sqlPack);
sqlPack += ")";
}
}
}

/// <summary>
Expand Down Expand Up @@ -394,7 +394,7 @@ private static void Trim(MethodCallExpression expression, SqlPack sqlPack)
{
sqlPack += ")";
}
}
}
}

/// <summary>
Expand All @@ -409,7 +409,7 @@ private static void TrimStart(MethodCallExpression expression, SqlPack sqlPack)
sqlPack += "LTRIM(";
SqlBuilderProvider.Where(expression.Object, sqlPack);
sqlPack += ")";
}
}
}

/// <summary>
Expand All @@ -424,7 +424,7 @@ private static void TrimEnd(MethodCallExpression expression, SqlPack sqlPack)
sqlPack += "RTRIM(";
SqlBuilderProvider.Where(expression.Object, sqlPack);
sqlPack += ")";
}
}
}
#endregion

Expand All @@ -439,9 +439,7 @@ public override SqlPack Where(MethodCallExpression expression, SqlPack sqlPack)
{
var key = expression.Method;
if (key.IsGenericMethod)
{
key = key.GetGenericMethodDefinition();
}
if (_Methods.TryGetValue(key.Name, out Action<MethodCallExpression, SqlPack> action))
{
action(expression, sqlPack);
Expand All @@ -460,17 +458,20 @@ public override SqlPack Insert(MethodCallExpression expression, SqlPack sqlPack)
{
var fields = new List<string>();
var array = expression.ToObject() as object[];
foreach (var item in array)
for (var i = 0; i < array.Length; i++)
{
sqlPack.Sql.Append("(");
var properties = item?.GetType().GetProperties();
if (sqlPack.DatabaseType != DatabaseType.Oracle)
sqlPack.Sql.Append("(");
if (i > 0 && sqlPack.DatabaseType == DatabaseType.Oracle)
sqlPack.Sql.Append(" UNION ALL SELECT ");
var properties = array[i]?.GetType().GetProperties();
foreach (var p in properties)
{
var type = p.DeclaringType.ToString().Contains("AnonymousType") ? sqlPack.DefaultType : p.DeclaringType;
(string columnName, bool isInsert, bool isUpdate) = sqlPack.GetColumnInfo(type, p);
if (isInsert)
{
var value = p.GetValue(item, null);
var value = p.GetValue(array[i], null);
if (value != null || (sqlPack.IsEnableNullValue && value == null))
{
sqlPack.AddDbParameter(value);
Expand All @@ -482,13 +483,14 @@ public override SqlPack Insert(MethodCallExpression expression, SqlPack sqlPack)
if (sqlPack[sqlPack.Length - 1] == ',')
{
sqlPack.Sql.Remove(sqlPack.Length - 1, 1);
sqlPack.Sql.Append("),");
if (sqlPack.DatabaseType != DatabaseType.Oracle)
sqlPack.Sql.Append("),");
else
sqlPack.Sql.Append(" FROM DUAL");
}
}
if (sqlPack.Sql[sqlPack.Sql.Length - 1] == ',')
{
sqlPack.Sql.Remove(sqlPack.Sql.Length - 1, 1);
}
sqlPack.Sql = new StringBuilder(string.Format(sqlPack.ToString(), string.Join(",", fields).TrimEnd(',')));
return sqlPack;
}
Expand Down
Loading

0 comments on commit c307933

Please sign in to comment.