Модифицированный актуальный список ссылок на удаляемую запись
Решил немного модифицировать функционалность отображения актуального списка ссылок на удаляемую запись (см. http://community.terrasoft.ua/blogs/3222). В частности, отображать только таблицы, на которые нет каскадных ключей и добавлять ID связанных записей.
Для этого в хранимой процедуре tsp_GetLinkedTablesByRecordID заменил SET @Result = @Result + @fTableName + char(13) + char(10) на SET @Result = @Result + @fTableName + ';'
В функции DeleteDataGridRecords (скрипт scr_WindowUtils) поменял
var TableName = Dataset.DeleteQuery.Table.SQLName;
if (!Connector.CurrentUser.IsAdmin) {
TableName = 'tbl_' + TableName.substr(3, TableName.length);
}
var DependedTablesText = GetLinkedTables(TableName, Dataset('ID'));
на
var TableName = Dataset.DeleteQuery.Table.SQLName;
var DependedTablesText = GetLinkedTables(TableName, Dataset('ID'));
и изменил функцию GetLinkedTables. Полный текст приведен ниже:
function GetLinkedTables(TableName, RecordID) {
if ((IsEmptyValue(TableName)) || (IsEmptyValue(RecordID))) {
return '';
}
var Parameters = System.CreateObject('TSObjectLibrary.Parameters');
var ReturnParameter = Parameters.CreateItem();
ReturnParameter.Name = 'Result';
ReturnParameter.ParamType = 2;
ReturnParameter.DataType = pdtGUID;
Parameters.Add(ReturnParameter);
var SqlTableName = TableName;
if (!Connector.CurrentUser.IsAdmin) {
SqlTableName = SqlTableName.replace('vw_','tbl_');
}
var sql = "exec tsp_GetLinkedTablesByRecordID '" + SqlTableName + "', '" +
RecordID + "', :Result output";
Connector.DBEngine.ExecuteCustomSQL(sql, Parameters);
var Result = Parameters.ItemsByName('Result').ValAsStr;
if (!IsEmptyValue(Result)) {
Result = Result.substr(0,Result.length-1);
var RefTablesResult = '';
var RefTableArray = Result.split(';');
for (var i = 0; i RefTableArray.length; i++) {
var RefTableName = RefTableArray[i];
try {
var RefTable = GetSingleItemByCode(RefTableName,'GetLinkedTables');
} finally {
if (Assigned(RefTable)){
Relations = RefTable.Relations;
for (var j = 0; j Relations.Count; j++) {
var Relation = Relations.Items(j);
var ParentTableName = Relation.ParentField.
ParentFields.ParentTable.SQLName;
if (!Relation.IsCascade&&(ParentTableName==TableName)){
RefTablesResult = RefTablesResult + RefTable.Caption +
' (' + RefTableName + ')' + ' Поле ' +
Relation.ChildField.Caption;
if (!Connector.CurrentUser.IsAdmin &&Relation.
ParentField.ParentFields.ParentTable.IsAdministratedByRecords){
var RefTableName = RefTableName.replace('tbl_','vw_');
}
var sql = 'select :Result = stuff((select \', \' + CAST(ID as nvarchar(38)) from ' + RefTableName;
var sql = sql +' WHERE ' + Relation.ChildField.SQLName + ' = \'' + RecordID +'\'';
var sql = sql +' for xml path (\'\')), 1,1,\'\')';
Parameters.ItemsByName('Result').Value = '';
try {
Connector.DBEngine.ExecuteCustomSQL(sql, Parameters);
} finally {
var ResultIDs = Parameters.ItemsByName('Result').ValAsStr;
if (!IsEmptyValue(ResultIDs)) {
RefTablesResult = RefTablesResult + ' IDs:' + ResultIDs;
}
}
RefTablesResult = RefTablesResult+ '\n';
}
}
} else {
RefTablesResult = RefTablesResult + RefTableName +
' (' + RefTableName + ')\n';
}
}
}
return RefTablesResult;
}
return '';
}
На первый взгляд:
1. ReturnParameter.DataType = pdtGUID; Почему гуид? Там же строка в которой через точку с запятой гуиды.
2. Почему где-то параметры, а где-то сразу в строку запроса значения вставляются? Надумано, но что будешь делать если в имени таблицы будет апостроф? Думаю лучше всегда использовать параметры.
3. Есть случаи когда даже при каскадных связях будут ошибки при удалении. А именно если кто-то ссылается на записи детали. Что-то типа такого:
Мастер 1 ->(каскадная связь) Деталь 1 ->(не каскадная связь) Таблица N