- 修复 sqlserver 解析 cast(.. as nvarchar) 截断长度 30 的问题;#335

This commit is contained in:
28810 2020-06-26 07:58:09 +08:00
parent 889af5e40c
commit dc8f575b18
4 changed files with 37 additions and 18 deletions

View File

@ -876,7 +876,7 @@ FROM [tb_topic22] a", subquery);
var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime]
FROM [tb_topic22] a FROM [tb_topic22] a
WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title]
FROM [tb_topic22] b)))", subquery); FROM [tb_topic22] b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }

View File

@ -925,7 +925,7 @@ FROM [tb_topic22] a", subquery);
var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime]
FROM [tb_topic22] a FROM [tb_topic22] a
WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title]
FROM [tb_topic22] b)))", subquery); FROM [tb_topic22] b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }

View File

@ -36,7 +36,10 @@ namespace FreeSql.Odbc.SqlServer
case "System.Int64": return $"cast({getExp(operandExp)} as bigint)"; case "System.Int64": return $"cast({getExp(operandExp)} as bigint)";
case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)"; case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)";
case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))";
case "System.String": return operandExp.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(operandExp)} as varchar(36))" : $"cast({getExp(operandExp)} as nvarchar)"; case "System.String":
return gentype == typeof(Guid) ?
$"cast({getExp(operandExp)} as varchar(36))" :
$"cast({getExp(operandExp)} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})";
case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)"; case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)";
case "System.UInt32": return $"cast({getExp(operandExp)} as int)"; case "System.UInt32": return $"cast({getExp(operandExp)} as int)";
case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)"; case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)";
@ -86,7 +89,10 @@ namespace FreeSql.Odbc.SqlServer
if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; if (callExp.Method.DeclaringType.IsNumberType()) return "rand()";
return null; return null;
case "ToString": case "ToString":
if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)") : null; var gentype2 = callExp.Object.Type.NullableTypeOrThis();
if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (gentype2 == typeof(Guid) ?
$"cast({getExp(callExp.Object)} as varchar(36))" :
$"cast({getExp(callExp.Object)} as nvarchar{(gentype2.IsNumberType() || gentype2.IsEnum ? "(100)" : "(max)")})") : null;
return null; return null;
} }
@ -262,10 +268,10 @@ namespace FreeSql.Odbc.SqlServer
case "Contains": case "Contains":
var args0Value = getExp(exp.Arguments[0]); var args0Value = getExp(exp.Arguments[0]);
if (args0Value == "NULL") return $"({left}) IS NULL"; if (args0Value == "NULL") return $"({left}) IS NULL";
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar)+'%')")}"; if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar(max))+'%')")}";
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar))")}"; if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar(max)))")}";
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar)+'%')"; return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar(max))+'%')";
case "ToLower": return $"lower({left})"; case "ToLower": return $"lower({left})";
case "ToUpper": return $"upper({left})"; case "ToUpper": return $"upper({left})";
case "Substring": case "Substring":
@ -336,7 +342,7 @@ namespace FreeSql.Odbc.SqlServer
switch (exp.Method.Name) switch (exp.Method.Name)
{ {
case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))";
case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar) + '-' + cast({getExp(exp.Arguments[1])} as varchar) + '-1')))"; case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar(100)) + '-' + cast({getExp(exp.Arguments[1])} as varchar(100)) + '-1')))";
case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})";
case "IsLeapYear": case "IsLeapYear":
@ -454,7 +460,7 @@ namespace FreeSql.Odbc.SqlServer
case "Subtract": return $"({left}-({args1}))"; case "Subtract": return $"({left}-({args1}))";
case "Equals": return $"({left} = {args1})"; case "Equals": return $"({left} = {args1})";
case "CompareTo": return $"({left}-({args1}))"; case "CompareTo": return $"({left}-({args1}))";
case "ToString": return $"cast({left} as varchar)"; case "ToString": return $"cast({left} as varchar(100))";
} }
} }
return null; return null;
@ -477,7 +483,11 @@ namespace FreeSql.Odbc.SqlServer
case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";
case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)";
case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))";
case "ToString": return exp.Arguments[0].Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(exp.Arguments[0])} as varchar(36))" : $"cast({getExp(exp.Arguments[0])} as nvarchar)"; case "ToString":
var gentype = exp.Arguments[0].Type.NullableTypeOrThis();
return gentype == typeof(Guid) ?
$"cast({getExp(exp.Arguments[0])} as varchar(36))" :
$"cast({getExp(exp.Arguments[0])} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})";
case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)";
case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)"; case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)";
case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";

View File

@ -36,7 +36,9 @@ namespace FreeSql.SqlServer
case "System.Int64": return $"cast({getExp(operandExp)} as bigint)"; case "System.Int64": return $"cast({getExp(operandExp)} as bigint)";
case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)"; case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)";
case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))";
case "System.String": return operandExp.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(operandExp)} as varchar(36))" : $"cast({getExp(operandExp)} as nvarchar)"; case "System.String": return gentype == typeof(Guid) ?
$"cast({getExp(operandExp)} as varchar(36))" :
$"cast({getExp(operandExp)} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})";
case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)"; case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)";
case "System.UInt32": return $"cast({getExp(operandExp)} as int)"; case "System.UInt32": return $"cast({getExp(operandExp)} as int)";
case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)"; case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)";
@ -86,7 +88,10 @@ namespace FreeSql.SqlServer
if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; if (callExp.Method.DeclaringType.IsNumberType()) return "rand()";
return null; return null;
case "ToString": case "ToString":
if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)") : null; var gentype2 = callExp.Object.Type.NullableTypeOrThis();
if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (gentype2 == typeof(Guid) ?
$"cast({getExp(callExp.Object)} as varchar(36))" :
$"cast({getExp(callExp.Object)} as nvarchar{(gentype2.IsNumberType() || gentype2.IsEnum ? "(100)" : "(max)")})") : null;
return null; return null;
} }
@ -262,10 +267,10 @@ namespace FreeSql.SqlServer
case "Contains": case "Contains":
var args0Value = getExp(exp.Arguments[0]); var args0Value = getExp(exp.Arguments[0]);
if (args0Value == "NULL") return $"({left}) IS NULL"; if (args0Value == "NULL") return $"({left}) IS NULL";
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar)+'%')")}"; if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar(max))+'%')")}";
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar))")}"; if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar(max)))")}";
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar)+'%')"; return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar(max))+'%')";
case "ToLower": return $"lower({left})"; case "ToLower": return $"lower({left})";
case "ToUpper": return $"upper({left})"; case "ToUpper": return $"upper({left})";
case "Substring": case "Substring":
@ -336,7 +341,7 @@ namespace FreeSql.SqlServer
switch (exp.Method.Name) switch (exp.Method.Name)
{ {
case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))";
case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar) + '-' + cast({getExp(exp.Arguments[1])} as varchar) + '-1')))"; case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar(100)) + '-' + cast({getExp(exp.Arguments[1])} as varchar(100)) + '-1')))";
case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})";
case "IsLeapYear": case "IsLeapYear":
@ -452,7 +457,7 @@ namespace FreeSql.SqlServer
case "Subtract": return $"({left}-({args1}))"; case "Subtract": return $"({left}-({args1}))";
case "Equals": return $"({left} = {args1})"; case "Equals": return $"({left} = {args1})";
case "CompareTo": return $"({left}-({args1}))"; case "CompareTo": return $"({left}-({args1}))";
case "ToString": return $"cast({left} as varchar)"; case "ToString": return $"cast({left} as varchar(100))";
} }
} }
return null; return null;
@ -475,7 +480,11 @@ namespace FreeSql.SqlServer
case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";
case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)";
case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))";
case "ToString": return exp.Arguments[0].Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(exp.Arguments[0])} as varchar(36))" : $"cast({getExp(exp.Arguments[0])} as nvarchar)"; case "ToString":
var gentype = exp.Arguments[0].Type.NullableTypeOrThis();
return gentype == typeof(Guid) ?
$"cast({getExp(exp.Arguments[0])} as varchar(36))" :
$"cast({getExp(exp.Arguments[0])} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})";
case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)";
case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)"; case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)";
case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";