Участник
Регистрация: 25.06.2009
Адрес: Омск
|
Баг в SysDictIndex
Актуальная версия аксапты: AX2012 R3, модификация совместима с более ранними версиями.
Еще в прошлом году нашел баг неверного составления SQL-запроса для поиска записей дубликатов, которые присутствуют в индексе.
Функция вызывается в контекстном меню по конкретному индексу.
Все бы хорошо, но в более ранних версиях, например в АХ4 она в принципе не работает.
Во-первых из-за того, что вызывается на клиенте.
Во-вторых, абсолютно неверно составляется запрос. Функцию невозможно было вызвать ни при каких условиях. Непонятно, как вообще она прошла в production.
В-третьих, хоть она и была исправлена в 2012, однако с некоторыми отключенными полями запрос все-равно формировался с ошибками.
В-четвертых, хотелось бы поменять порядок на более удобный - по убыванию количества дубликатов.
X++: void showDuplicates()
{
// > inserted by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
#define.DataAreaNo(2)
// < inserted by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
tableId tableId = this.tableid();
DictTable dictTable = new DictTable(tableId);
boolean dataPrCompany = dictTable.dataPrCompany();
Counter numberOfFields = this.numberOfFields();
Counter i;
str stmtStr;
str resultLineStr;
str resultField;
str resultField1;
UserConnection con = new UserConnection();
Statement stmt = con.createStatement();
ResultSet resultSet;
boolean anyDuplicates = false;
DictField dField;
str tableNameWithSchema;
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
Map fields = new Map(Types::Integer, Types::String);
MapEnumerator enumerator;
Counter fieldsCount = #DataAreaNo;
str fieldList;
str orderList;
int key;
str fieldName;
// > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
//container fields;
//int enabledFields[];
//Counter enabledFieldCounter;
//SqlStatementExecutePermission ssep;
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
;
if (dataPrCompany)
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
{
fields.insert(fieldsCount, dictTable.fieldName(fieldnum(Common, DataAreaId), DbBackend::Sql));
fieldsCount++;
}
// > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
// fields += dictTable.fieldName(fieldnum(Common,DataAreaId),DbBackend::Sql);
//
//enabledFieldCounter = 0;
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
for (i = 1; i <= numberOfFields; i++)
{
dField = new DictField(tableId, this.field(i));
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
if (dField.isSql() && dfield.id() != fieldnum(Common, DataAreaId))
{
fields.insert(fieldsCount, dictTable.fieldName(this.field(i), DbBackend::Sql));
fieldsCount++;
}
// > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
//if( dField.isSql() == false )
// continue;
//++enabledFieldCounter;
//enabledFields[enabledFieldCounter] = i;
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
}
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
stmtStr = 'select count(*), ';
enumerator = fields.getEnumerator();
while (enumerator.moveNext())
{
if (any2int(enumerator.currentKey()) != #DataAreaNo)
{
fieldList += ', ';
orderList += ', ';
}
fieldList += any2str(enumerator.currentValue());
orderList += int2str(any2int(enumerator.currentKey()));
}
stmtStr += fieldList;
// > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
//for (i = 1; i <= enabledFieldCounter; i++)
//{
// fields += dictTable.fieldName(this.field(enabledFields[i]), DbBackend::Sql);
//}
//
//stmtStr = 'select count(*)';
//for (i = 1; i <= enabledFieldCounter; i++)
//{
// stmtStr += ', ' + dictTable.fieldName(this.field(enabledFields[i]),DbBackend::Sql,0,FieldNameGenerationMode::FieldListGroupBy);
//}
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
tableNameWithSchema = xSession::getDbSchema();
if (tableNameWithSchema != '')
tableNameWithSchema += '.'+ dictTable.name(DbBackend::Sql);
else
tableNameWithSchema = dictTable.name(DbBackend::Sql);
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
stmtStr += strfmt(' from %1 group by %2', tableNameWithSchema, fieldList);
// > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
//stmtStr += ' from ' + tableNameWithSchema;
//stmtStr += ' group by ';
//for (i = 1; i <= enabledFieldCounter; i++)
//{
// if (i > 1)
// stmtStr += ', ';
// stmtStr += dictTable.fieldName(this.field(enabledFields[i]),DbBackend::Sql,0,FieldNameGenerationMode::GroupByFieldList);
//}
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
stmtStr += ' having count(*) > 1';
if (numberOfFields > 0)
{
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
stmtStr += ' order by 1 desc, ';
stmtStr += orderList;
// > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
//stmtStr += ' order by ';
//for (i = 1; i <= enabledFieldCounter; i++)
//{
// if (i > 1)
// stmtStr += ', ';
// stmtStr += int2str(enabledFields[i]+1);
//}
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
stmtStr += ' desc';
}
// dangerous API mitigation
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
new SqlStatementExecutePermission(stmtStr).assert();
// > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
//ssep = new SqlStatementExecutePermission(stmtStr);
//ssep.assert();
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
// BP Deviation Documented
resultSet = stmt.executeQuery(stmtStr);
while (resultSet.next())
{
resultLineStr = "@SYS283" + strfmt(': %1', resultSet.getString(1));
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
enumerator.reset();
while (enumerator.moveNext())
{
key = any2int(enumerator.currentKey());
fieldName = any2str(enumerator.currentValue());
resultField = strLRTrim(resultSet.getString(key));
if (dataPrCompany && key == #DataAreaNo)
resultField1 = resultField;
else
resultLineStr += strfmt(", %1: '%2'", fieldName, resultField);
}
// > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
//for (i = 1; i <= numberOfFields; i++)
//{
// resultField = strltrim(resultSet.getString(enabledFields[i]+1));
// if (i == 1 && dataPrCompany)
// resultField1 = resultField;
// else
// resultLineStr += strfmt(', %1: \'%2\'', conpeek(fields, enabledFields[i]), resultField);
//}
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
if (dataPrCompany)
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
setprefix(strfmt("%1: %2", fieldstr(Common, DataAreaId), resultField1));
// > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
//setprefix(strfmt('%1: %2', conpeek(fields, 1), resultField1));
// < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
info(resultLineStr);
anyDuplicates = true;
}
if (!anyDuplicates)
info("@SYS68671");
}
__________________
// no comments
|