Вопрос

Добрый день!

Пробую реализовывать запрос к данных через ESQ таким образом:

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
                    rootSchemaName: "UsrTbl1"
                });
                esq.addColumn("Id");
                esq.addColumn("UsrPar1");esq.addColumn("UsrInfoId");
                esq.addColumn("UsrValueList.Name");//вот с такими строками уже начинается проблема

esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrValueList.Name", "значение1"));//и с такими фильтрами

 

Если нужно получить значение колонок с таблицы - rootSchemaName, то не вопрос.

Проблемы начинаются, когда пытаюсь использовать прямые ссылки или в одной запросе получать GUID, а во втором его использовать.

GUID  видимо со String плохо понимают друг друга. Если ли примеры их нормального совместного использования в рамках ESQ?

Можно ли как-то понять причины неработоспособности прямых ссылок? Или хотя бы понять как с GUID быть? Даже если я значение GUID пытаюсь вставлять так, то не работает:

esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrInfoId", "337ED96B-B658-48B0-BBB6-7FACF918C735"));

У меня такой же вопрос

2 комментария
Лучший ответ

Eсли нужно получить справочную колонку, то её название нужно указывать без приставки "Id", как в схеме таблицы:

esq.addColumn("UsrInfo")

Аналогично и с фильтрами:

esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrInfo", "337ED96B-B658-48B0-BBB6-7FACF918C735"));

Но обратите внимание, что, если у Вас фильтр построен по обратным связям, то можно писать 2 способами.

1. Через Id и тогда в качестве значения фильтра указываем Id:

var shipment = this.get("BTShipment");

sampleESQ.filters.addItem(sampleESQ.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.EQUAL, "[BTSampInShipment:BTSampleID].BTShipment.Id", shipment.value));

2. Через справочное поле и тогда в качестве значения указывать значение справочного поля:

var shipment = this.get("BTShipment");

sampleESQ.filters.addItem(sampleESQ.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.EQUAL, "[BTSampInShipment:BTSampleID].BTShipment", shipment));

А вообще, чтобы понять причину ошибки нужно отладиться на стороне клиента, если запрос уходит в базу данных, то посмотреть в SQL profiler, какой запрос идет в базу и какой результат работы этого запроса.

 

В js все Guid преобразуйте к нижнему регистру

те в вашем случае напишите что то типа esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrInfoId", "337ed.....

Eсли нужно получить справочную колонку, то её название нужно указывать без приставки "Id", как в схеме таблицы:

esq.addColumn("UsrInfo")

Аналогично и с фильтрами:

esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrInfo", "337ED96B-B658-48B0-BBB6-7FACF918C735"));

Но обратите внимание, что, если у Вас фильтр построен по обратным связям, то можно писать 2 способами.

1. Через Id и тогда в качестве значения фильтра указываем Id:

var shipment = this.get("BTShipment");

sampleESQ.filters.addItem(sampleESQ.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.EQUAL, "[BTSampInShipment:BTSampleID].BTShipment.Id", shipment.value));

2. Через справочное поле и тогда в качестве значения указывать значение справочного поля:

var shipment = this.get("BTShipment");

sampleESQ.filters.addItem(sampleESQ.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.EQUAL, "[BTSampInShipment:BTSampleID].BTShipment", shipment));

А вообще, чтобы понять причину ошибки нужно отладиться на стороне клиента, если запрос уходит в базу данных, то посмотреть в SQL profiler, какой запрос идет в базу и какой результат работы этого запроса.

 

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Сущности в системе идентифицируются Guid. который, будучи преобразованным в строку, имеет вид типа "846d8d33-004b-4a3e-b778-10cfd163f3bb" (буквы строчные, в таком виде он фигурирует, например, в параметрах запросов http)

С другой стороны в БД сущности хранятся с первичным ключем, построенным на id varchar2(38), но содержиное там заключено в фигурные скобки и буквы заглавные.

Есть ли стандартная функция преобразования одного в другое? В запрос нужно передать Id текущего контакта, но "{"+UserConnection.CurrentUser.ContactId.ToUpper()+"}" выглядит достаточно неуклюже.

У меня такой же вопрос

12 комментариев

Могу предложить "элегантный костыль":
string contact = "846d8d33-004b-4a3e-b778-10cfd163f3bb";
string result = String.Join(String.Empty, "{", contact.ToUpper(), "}");

Если используете механизмы EntityShchemaQuery или Select/Insert/Update/Delete, то ничего преобразовывать не нужно, в функции передаётся переменная типа Guid и при генерации SQL в нужном формате подставится само. Если же самостоятельно создаёте SQL, воспользуйтесь своим кодом или советом выше.

Эелегантность костыля в виде сокращения записи обращения к переменной иррелевантна задаче :)

Меня больше интересовал источник подобных сложностей, почему сразу было не привести к одному формату? Ведь была ж какая-то причина?

Причина в том, что основная поддерживаемая база  — MS SQL, где есть тип «uniqueidentifier» и база поймёт вставку в любом формате. А поддержка Oracle добавлена опционально.

В этом и была суть вопроса: если в Oracle используется просто текст, какая разница, что туда писать? Зачем эти скобочки? Чтобы что-то в базе посмотреть, скопировать Id из URL не получится, это минус. Как и при склеивании ESQ и Select. А плюсы вообще есть?

Этот текст, хоть и не является отдельным типом «uniqueidentifier», но служит в качестве первичного или внешнего ключа. Соответственно, если писать в двух полях один GUID разным способом, связи между ними не получится.

Зверев Александр,

В каких 2-х полях??? Почему не писать ОДНИМ способом, в нижнем регистре и без скобок? Везде.

В версии для MS SQL пишите как вам нужно, а в Oracle — именно требуемым способом.

Зверев Александр,

Спасибо, я ожидал компетентный ответ, а не бессмысленный совет следовать инструкциям, я им и так следую, но не могу понять необходимость такого усложнения и препятствия к его устранению. Если препятствий нет, то, думаю,  все, кто на Oracle, меня поддержат, было бы хорошо привести все к единому знаменателю.

Дмитрий, оно и приведено к единому знаменателю — с фигурными скобками в верхнем регистре. Нет смысла в версиях с 3.0 по 7.13 использовать один формат, а потом внезапно менять просто потому, что не нравятся скобки.

Я написал, что не нравится: дело не в скобках, а в отсутствии целостности восприятия. Я понял, что это чье-то давнишнее головотяпство, последствия которого сейчас уже сложно ликвидировать, а негативное влияние считается минимальным. При этом корпоративная этика не позволяет это признать на людях. В принципе, лучше было вообще не реагировать на мой вопрос, но в любом случае спасибо.

При обычной работе с форматом написания не сталкиваются никак, все C#-классы принимают значения типа Guid и преобразуют в нужный формат при генерации SQL автоматически. В чём именно негативное влияние фигурных скобок, Вы так и не объяснили. 

Вероятно, первоисточник именно такого написания — стандартная функция CreateGuid в Delphi, на котором была написана система Terrasoft 3.X. Она генерирует именно в таком формате. И в таблицу базы Firebird и Oracle, где нет встроенных типов для хранения GUID, так и записывали.

В Microsoft для C# рекомендуют для получения нужного формата использовать для переменной типа Guid метод ToString("N") в сочетании с String.ToUpper.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Здравствуйте,
Всплывает ошибка при загрузке мастера редактирования карточки:

file: undefined
line: undefined
column: undefined
message: Элемент с ключом 33e46153-d870-42af-a250-8d8a9ecae940 Не существует 
 date: Thu Nov 15 2018 16:02:43 GMT+0500 (Екатеринбург, стандартное время)
moduleId: undefined
moduleName: undefined

Пишет что id не найден, смотрел в БД, таблицу SysSchema там реально этого UId нету, но зато есть эта карточка но с другим Id
Почему так могло произойти ? И как это можно исправить ?

У меня такой же вопрос

2 комментария

Уточните, возникают ли какие-то ошибки в консоли просто при открытии этой карточки редактирования?

Возможно, что-то не перенеслось, если эти карточки переносили на основной сайт с базы разработки. 

Попробуйте сравнивать наполнение системных таблиц, связанных с разделами (вроде SysModule, SysModuleEdit и т.д.) для этого и для нормально работающего разделов. Либо произведите автоматический поиск по всем полям всех таблиц базы, чтобы найти, где именно записан этот ID 33e46153-d870-42af-a250-8d8a9ecae940.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Приветы,

 

Подскажите плиз, как правильно сделать, создал объект наследуемый от базового и добавил поле BpCandidate как строка 50 символов в конструкторе объекта.

 

Пробовал сделать поле типа справочник и тогда оно становится Guid в коде

В следующем коде было вместо TEXT, у поля BpCandidate указан GUID

Так вот в консоли хрома видел ошибку уровня c#, а именно System.String не могу преобразовать в System.Guid и как быть? 

 

Удалив столбец, пересохранив и добавив его снова как строка 50 символов и вернув ТЕКСТ вместо ГУИД все заработало, но как быть с гуидами в инсерт запросами???

 

insertCount: function (candId) {
                this.logStep('insertCount started...');

                var insertQuery = this.Ext.create("Terrasoft.InsertQuery", {
                    rootSchemaName: "BpCandidateCall"
                });

                insertQuery.setParameterValue("CallCount",
                    1,
                    this.Terrasoft.DataValueType.INTEGER);

                insertQuery.setParameterValue("BpCandidate",
                    candId,
                    this.Terrasoft.DataValueType.TEXT);

                var dt = new Date();
                insertQuery.setParameterValue("CallDate",
                    dt,
                    this.Terrasoft.DataValueType.DATE);

                insertQuery.setParameterValue("CallTime",
                    dt,
                    this.Terrasoft.DataValueType.TIME);
                insertQuery.execute(function () {
                    //this.loadActivities();
                }, this);

                this.logStep('insertCount finished...');
            },

У меня такой же вопрос

1 комментарий

А что если колонка в базе будет GUID, а в коде выше DataValueType.TEXT?

Войдите или зарегистрируйтесь, чтобы комментировать
Идея

Если добавить возможность в фильтрах сравнивать Guid'ы по больше/меньше то появится возможность довольно просто реализовать цикл перебора записей в БП (сортировка по Id + Id > Id_спрошлойитерации). Сейчас для них присутствуют возможности сравнения как для строки, что не очень юзабельно.Ну или сам функционал перебора выборок.

Не планируется
9 комментариев

А разве Guid'ы генерируются по-порядку?

"Владимир Соколов" написал:

А разве Guid'ы генерируются по-порядку?


для цикла достаточно того, что они сортируются и сравниваются больше/меньше по одному и тому же алгоритму (хотя я не проверял достаточно дотошно)

правда, есть такой момент, что выборка может измениться, пока она перебирается. И хотя это никак не помешает процессу, но может давать несколько неожиданные результаты: 1) обработается больше записей, чем ожидалось на момент начала цикла (если, например, перед циклом было выбрано кол-во записей для выборки) 2) какие-то из вновь добавленных записей не обработаются, т.к. их ИД будет меньше ИД записи, обрабатываемой в текущий момент

Вообще, длинные циклы на уровне движка БП — не лучшая идея. Для этого больше подходит блок БП «скрипт» с нужным программированием внутри.

"Зверев Александр" написал:

Вообще, длинные циклы на уровне движка БП — не лучшая идея. Для этого больше подходит блок БП «скрипт» с нужным программированием внутри.


1) это если ты можешь написать этот код.
2) цикл вовсе не обязан быть длинным

Здравствуйте!

Сравнивайте по полю "Дата изменения". Точность этого поля - милисекунды. По этой причине нет двух записей с одинаковой датой модификации.

Дмитрий, информацию передали в департамент разработки для рассмотрения реализации.

Здравствуйте! 

Пока не планируем давать возможность в фильтрах сравнивать Guid'ы по больше/меньше.

Но планируем в ближайший версиях дать возможность пользовательскими средствами настраивать обработку коллекций записей. А именно: научим Чтение данных формировать коллекции и доработаем элемент Подпроцесс, в рамках которого можно будет запустить множество экземпляров процесса (multi instance subprocess).  

Подскажите, такая функциональность решила бы те задачи, которые вы реализовываете с помощью перебора записей в циклах?

 

Марина Бельмега,

конечно, как и указано в топике

Войдите или зарегистрируйтесь, чтобы комментировать
Публикация

Добрый день!

Часто при построении бизнес-процессов (далее БП) мы сталкиваемся с необходимостью выполнить проверку - заполнено поле или нет.
В данной статье рассмотрим, как выполнить проверку заполнения поля справочного типа. Например, после закрытия сделки на странице контрагента необходимо выполнить проверку, - установлен ли «Основной контакт». Если установлен – запланировать плановый звонок через месяц, если нет – поставить задачу «Актуализировать информацию об основном контакте».
Схема БП выглядит следующим образом:

http://i70.fastpic.ru/big/2015/0603/91/709c8c75b6434dad3d06bd39d30a2b91.png

На что необходимо обратить внимание:
1. В первую очередь вы должны используя элемент чтения данных прочитать нужный параметр (в нашем примере поле «Основной контакт» на странице контрагента.
2. При ветвлении процесса не забывайте использовать поток по умолчанию, для того, чтобы процесс не зависал, если не выполнилось условие.

И главное:
3. Проверка заполнения поля справочного типа выполняется следующим образом:

http://i72.fastpic.ru/big/2015/0603/a1/4ebe84b6b46bbef309aa844c0c05b8a1.png

ПРИМЕЧАНИЕ: В базе данных в полях справочного типа хранится идентификатор данного справочного значения, а это поле типа «Guid» и его необходимо сравнивать с пустой константой «Guid.Empty».
После завершения построения диаграммы БП опубликуйте изменения и проверьте корректность работы процесса.

Поделиться

0 комментариев
Войдите или зарегистрируйтесь, чтобы комментировать
Публикация

Коллеги, здравствуйте.

В ходе выполнения различного рода задач может пригодится скрипт, который выполнит поиск заданного идентификатора по всей базе данных (в колонке с определенным названием).

DECLARE @COLUMN_NAME NVarChar(100) = 'Id'
DECLARE @COLUMN_VALUE NVarChar(100) = '8F2E3098-932C-49A8-8D06-B40462DA98CD'

DECLARE @tableName VARCHAR(50)
DECLARE tablesCursor CURSOR LOCAL FORWARD_ONLY STATIC FOR
               
                SELECT table_name = sysobjects.name
                FROM sysobjects
                JOIN syscolumns ON sysobjects.id = syscolumns.id        
                WHERE sysobjects.xtype='U'
                AND syscolumns.name = @COLUMN_NAME

OPEN tablesCursor
FETCH NEXT FROM tablesCursor INTO @tableName

WHILE @@FETCH_STATUS = 0
BEGIN  
               
                EXEC ('DECLARE @recordCount INT;
                               DECLARE @quotesChar CHAR = char(39);
                               DECLARE @tabChar CHAR = char(9);
                               BEGIN TRY
                                               SET @recordCount =
                                                               (SELECT COUNT(*)
                                                               FROM ['
+ @tableName + '] where ' + @COLUMN_NAME + ' = ''' + @COLUMN_VALUE + ''')
                                               IF @recordCount > 0
                                               BEGIN                                                  
                                                               PRINT '
'''
                                                               PRINT '
'-- ' + @tableName + ':''
                                                               PRINT '
'     SELECT * FROM ' + @tableName +
                                                                                                              ' WHERE ' + @COLUMN_NAME +
                                                                                                              ' = '' + @quotesChar + ''' + @COLUMN_VALUE + ''' + @quotesChar + ''''                                          
                                                               PRINT '
'     -- Количество строк в запросе: '' + CAST(@recordCount as VARCHAR(5))
                                               END
                               END TRY
                               BEGIN CATCH                                  
                               END CATCH;                      
                               '
);
                FETCH NEXT FROM tablesCursor INTO @tableName
END

CLOSE tablesCursor
DEALLOCATE tablesCursor

Поделиться

0 комментариев
Войдите или зарегистрируйтесь, чтобы комментировать
Публикация

Для того, чтобы в коде создать объект воспользуйтесь следующим примером кода:

var entitySchemaManager = Page.Schema.SchemaManagerProvider.GetManager("EntitySchemaManager") as EntitySchemaManager;
var contactSchemaQuery = new EntitySchemaQuery(entitySchemaManager, "Contact"); //название схемы объекта
contactSchemaQuery.AddColumn(contactSchemaQuery.RootSchema.GetPrimaryColumnName());
contactSchemaQuery.AddColumn("Dear"); // определяем каждую из колонок, с которыми мы будем работать

contactSchemaQuery.Filters.Add(campaign contactSchemaQuery.CreateFilterWithParameters(
         FilterComparisonType.Equal,
         "Id",
        new Guid("14e6a3c6-920b-4e27-9274-7c9b071d79d3"))); //фильтр запроса
var contactEntity = contactSchemaQuery.GetEntityCollection(UserConnection);

contactEntity – это DataSource, из которого можно получить значения для тех колонок, которые мы определили в начале.

Поделиться

0 комментариев
Войдите или зарегистрируйтесь, чтобы комментировать