From f29d2e49eb7d3e9c1ba4801db65a0a00890dc47b Mon Sep 17 00:00:00 2001 From: cmurialdo Date: Mon, 17 Oct 2022 18:03:17 -0300 Subject: [PATCH] Fix error ORA-01795: maximum number of expressions in a list is 1000 error Split list of items on IN expression for Oracle SQLs. --- .../GxClasses/Data/GXDataCommon.cs | 95 +++++++++++++++++-- .../GxClasses/Data/GXDataOracle.cs | 2 +- 2 files changed, 86 insertions(+), 11 deletions(-) diff --git a/dotnet/src/dotnetframework/GxClasses/Data/GXDataCommon.cs b/dotnet/src/dotnetframework/GxClasses/Data/GXDataCommon.cs index 6c3839d11..7b76b8b47 100644 --- a/dotnet/src/dotnetframework/GxClasses/Data/GXDataCommon.cs +++ b/dotnet/src/dotnetframework/GxClasses/Data/GXDataCommon.cs @@ -25,6 +25,7 @@ using System.Globalization; using GeneXus.Metadata; using System.Data.Common; +using System.Linq; namespace GeneXus.Data { @@ -140,6 +141,7 @@ IDataReader GetDataReader(IGxConnectionManager connManager, IGxConnection connec void SetCursorDef(CursorDef cursorDef); string ConcatOp(int pos); string AfterCreateCommand(string stmt, GxParameterCollection parmBinds); + int MaxNumberOfValuesInList { get; } } @@ -945,6 +947,9 @@ public virtual string DataSource get {return m_datasource;} set{m_datasource=value;} } + + public virtual int MaxNumberOfValuesInList => int.MaxValue; + public string ConnectionStringForLog() { string result=""; @@ -3705,6 +3710,76 @@ public GxDbmsUtils(IGxDataRecord db) { dbmsHandler = db; } + IEnumerable> Split(T[] arr, int size) + { + for (int i = 0; i < arr.Length / size + 1; i++) + { + yield return arr.Skip(i * size).Take(size); + } + } + IEnumerable Split(IList values, int size) + { + IList list = new List(size); + + foreach (object item in values) + { + list.Add(item); + if (list.Count == size) + { + yield return list; + list = new List(size); + } + } + if (list.Count != 0) + { + yield return list; + } + } + string ChunkValueList(T[] values, string prefix, string postfix) + { + StringBuilder stringBuilder = new StringBuilder(); + if (values.Length > dbmsHandler.MaxNumberOfValuesInList) + { + foreach (T[] svalues in Split(values, dbmsHandler.MaxNumberOfValuesInList)) + { + if (stringBuilder.Length > 0) + stringBuilder.Append(" OR "); + stringBuilder.Append(prefix); + stringBuilder.Append(ValueList(svalues)); + stringBuilder.Append(postfix); + } + } + else + { + stringBuilder.Append(prefix); + stringBuilder.Append(ValueList(values)); + stringBuilder.Append(postfix); + } + return stringBuilder.ToString(); + } + string ChunkValueList(IList values, string prefix, string postfix) + { + StringBuilder stringBuilder = new StringBuilder(); + if (values.Count > dbmsHandler.MaxNumberOfValuesInList) + { + foreach (IList svalues in Split(values, dbmsHandler.MaxNumberOfValuesInList)) + { + if (stringBuilder.Length > 0) + stringBuilder.Append(" OR "); + stringBuilder.Append(prefix); + stringBuilder.Append(ValueList(svalues)); + stringBuilder.Append(postfix); + } + } + else + { + stringBuilder.Append(prefix); + stringBuilder.Append(ValueList(values)); + stringBuilder.Append(postfix); + + } + return stringBuilder.ToString(); + } public string ValueList(short[] Values, string Prefix, string Postfix) { if (Values == null || Values.Length == 0) @@ -3713,7 +3788,7 @@ public string ValueList(short[] Values, string Prefix, string Postfix) } else { - return Prefix + ValueList(Values) + Postfix; + return ChunkValueList(Values, Prefix, Postfix); } } public string ValueList(int[] Values, string Prefix, string Postfix) @@ -3724,7 +3799,7 @@ public string ValueList(int[] Values, string Prefix, string Postfix) } else { - return Prefix + ValueList(Values) + Postfix; + return ChunkValueList(Values, Prefix, Postfix); } } public string ValueList(long[] Values, string Prefix, string Postfix) @@ -3735,7 +3810,7 @@ public string ValueList(long[] Values, string Prefix, string Postfix) } else { - return Prefix + ValueList(Values) + Postfix; + return ChunkValueList(Values, Prefix, Postfix); } } public string ValueList(decimal[] Values, string Prefix, string Postfix) @@ -3746,7 +3821,7 @@ public string ValueList(decimal[] Values, string Prefix, string Postfix) } else { - return Prefix + ValueList(Values) + Postfix; + return ChunkValueList(Values, Prefix, Postfix); } } public string ValueList(float[] Values, string Prefix, string Postfix) @@ -3757,7 +3832,7 @@ public string ValueList(float[] Values, string Prefix, string Postfix) } else { - return Prefix + ValueList(Values) + Postfix; + return ChunkValueList(Values, Prefix, Postfix); } } public string ValueList(double[] Values, string Prefix, string Postfix) @@ -3768,7 +3843,7 @@ public string ValueList(double[] Values, string Prefix, string Postfix) } else { - return Prefix + ValueList(Values) + Postfix; + return ChunkValueList(Values, Prefix, Postfix); } } public string ValueList(DateTime[] Values, string Prefix, string Postfix) @@ -3779,7 +3854,7 @@ public string ValueList(DateTime[] Values, string Prefix, string Postfix) } else { - return Prefix + ValueList(Values) + Postfix; + return ChunkValueList(Values, Prefix, Postfix); } } public string ValueList(string[] Values, string Prefix, string Postfix) @@ -3790,7 +3865,7 @@ public string ValueList(string[] Values, string Prefix, string Postfix) } else { - return Prefix + ValueList(Values) + Postfix; + return ChunkValueList(Values, Prefix, Postfix); } } public string ValueList(bool[] Values, string Prefix, string Postfix) @@ -3801,7 +3876,7 @@ public string ValueList(bool[] Values, string Prefix, string Postfix) } else { - return Prefix + ValueList(Values) + Postfix; + return ChunkValueList(Values, Prefix, Postfix); } } public string ValueList(IList Values, string Prefix, string Postfix) @@ -3812,7 +3887,7 @@ public string ValueList(IList Values, string Prefix, string Postfix) } else { - return Prefix + ValueList(Values) + Postfix; + return ChunkValueList(Values, Prefix, Postfix); } } public string ValueList(short[] Values) diff --git a/dotnet/src/dotnetframework/GxClasses/Data/GXDataOracle.cs b/dotnet/src/dotnetframework/GxClasses/Data/GXDataOracle.cs index 2467150b6..ec1d3ad19 100644 --- a/dotnet/src/dotnetframework/GxClasses/Data/GXDataOracle.cs +++ b/dotnet/src/dotnetframework/GxClasses/Data/GXDataOracle.cs @@ -961,7 +961,7 @@ public override IGeographicNative GetGeospatial(IGxDbCommand cmd, IDataRecord DR return gtmp; } } - + public override int MaxNumberOfValuesInList => 1000; public override bool AllowsDuplicateParameters { get