Здравствуйте. Такая проблема: не фильтруется датасет по CustomSQLColumn.
Попробовал сделать через OnQuickFilter, как советовали в https://community.terrasoft.ru/blogs/4397 , тоже не работает.
Как заставить его работать? В таблице дублировать данные очень нежелательно.
Спасибо.
Нравится
Здравствуйте, Ринат!
Если он пустой, значит, он фильтруется. Просто не совпадают значения и содержимое.
Если бы он не фильтровался - тогда бы просто всегда вверху было первое значение.
Рекомендую Вам просто вывести рядом значение, по которому фильтруете, и значение датасета, которое хотите отфильтровать. Вероятнее всего, несовпадение синтаксиса.
Как альтернативный вариант, оберните CustomSQLColumn в subselect. Есть такая небольшая недокументированная фича. :) Т.е. создаете в SelectQuery подзапрос по таблице, у которой по любому есть только одна запись (лучше создать такую и добавить в нее одну запись). Потом в подзапросе добавляете CustomSQLColumn и реализуете в ней все, что хотите. И все. Далее в ядре подзапрос успешно "оборачивается" и при выполнении сортировки, и фильтраций, и при использовании итогов по нему. Можете проверить этот вариант (просто не во всех версиях он работает).
Через subquery не получилось.
SelectQuery формируется правильно, но по-моему параметр не передаётся в запрос
... WHERE ("tbl_Houses"."HouseAddress" || "tbl_Incident"."Flat" like '%' || :pFullAddress_U || '%')
В террасофте параметр FullAddress создан, значение ему присваивается.
Вызывается так:
function grdDataOnQuickFilter(DataGrid, DataField, Value, QuickFilterLikeType, DoFilter, DoQuickFilter) { debugger; if(DataField.Name == 'FullAddress') { var Dataset = DataGrid.DatasetLink.Dataset; ApplyDatasetFilter(Dataset, 'FullAddress', Value, true);
Для того, чтобы фильтр отработал, необходимо выполнить запрос, то есть, обновить датасет. То есть, закрыть его и открыть заново.
То есть, после
var Dataset = DataGrid.DatasetLink.Dataset; ApplyDatasetFilter(Dataset, 'FullAddress', Value, true);
добавить
Dataset.Close(); Dataset.Open();
Всё равно пусто.
Копирую сформированный SelectQuery из дебага, подставляю на место :pFullAddress реальный адрес 'Лермонтова', SelectQuery работает.
Может, мне Пользовательский SQL-фильтр переписать? Как-нибудь параметр по-другому передавать?
Сейчас он такой:
UPPER("tbl_Houses"."HouseAddress" || "tbl_Incident"."Flat") like '%' || :pFullAddress_U || '%'
Ринат, рекомендую Вам посмотреть профайлером.
Что касается фильтра, рекомендую Вам попробовать следующую конструкцию:
UPPER("tbl_Houses"."HouseAddress" || "tbl_Incident"."Flat") LIKE '%' + :pFullAddress_U + '%'
А что в итоге идет в базу данных? Пробовали смотреть запросы профайлером?
Что касается объединения строк, Можете попробовать так:
CONCAT(CONCAT('%', :pFullAddress_U)), '%')
Не пойму, зачем Вы фильтр накладываете на OnQuickFilter, т.е. после того, как пользователь в гриде уже применил быстрый фильтр. Т.е. датасет уже открылся и уже что-то делать поздно. По моему, мы не туда "копаем". Можете описать задачу детальнее?
Есть такой вот Пользовательский SQL-фильтр в sq_Incidents:
UPPER("tbl_Houses"."HouseAddress" || "tbl_Incident"."Flat") LIKE '%' || :pFullAddress_U || '%'
В датасет он попадает, но датасет по нему не фильтруется, т.к. не всё так просто с этим фильртом, он берёт "адрес дома" из объединённой таблицы и конкатенирует с "квартирой" из основной.
(Сам инцидент привязывается к ID дома, на котором он произошёл, но также важен поиск по полному адресу)
Есть параметр FullAddress (:pFullAddress).
Наверное, всё же придётся дублировать данные в таблице инцидентов...
Просто в сабже Вы писали о CustomSQLColumn и я решил, что Вам нужна возможность фильтрации по такой колонке. Ладно.
1. Согласно Вашего sql-запроса параметр должен называться FullAddress_U, а не FullAddress. Наша engine потом сама добавит при анализе запроса :p и получится :pFullAddress_U.
2. В SQLMonitor-е как запрос целиком отображается (вместе с параметрами и их значениями)?
Вот отрывок трейс-файла оракл, назвал параметр FullAddress_U без :p
*** 2012-01-20 03:58:07.109 CLOSE #139785163541904:c=0,e=13,dep=0,type=3,tim=1327010287108998 PARSE #139785163540784:c=0,e=241,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=376016973,tim=1327010287109350 EXEC #139785163540784:c=1000,e=136,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=376016973,tim=1327010287109521 FETCH #139785163540784:c=2000,e=2200,p=0,cr=144,cu=0,mis=0,r=1,dep=0,og=1,plh=376016973,tim=1327010287111884 FETCH #139785163540784:c=0,e=150,p=0,cr=0,cu=0,mis=0,r=39,dep=0,og=1,plh=376016973,tim=1327010287114409 CLOSE #139785163540784:c=0,e=11,dep=0,type=3,tim=1327010287399713 ===================== PARSING IN CURSOR #139785163649936 len=3226 dep=0 uid=478 oct=3 lid=479 tim=1327010287400513 hv=2088716702 ad='953aafc0' sqlid='d3dkqjty7ykcy' SELECT "ID", "IncidentNumber", "AccountID", "ActualDueDate", "ContactID", "Date", "DueDate", "IncidentTypeID", "IncidentTypeName", "OfferingID", "OwnerID", "OwnerName", "PriorityID", "StatusID", "StatusName", "Synopsis", "StatusIsFinish", "ResponseLastDate", "ResponseDelay", "HouseAddressText", "Flat", "FullAddress", "HouseRegion", "HouseRegionName" FROM ( SELECT "tbl_Incident"."ID" "ID", "tbl_Incident"."IncidentNumber" "IncidentNumber", "tbl_Incident"."AccountID" "AccountID", "tbl_Incident"."ActualDueDate" "ActualDueDate", "tbl_Incident"."ContactID" "ContactID", "tbl_Incident"."Date" "Date", "tbl_Incident"."DueDate" "DueDate", "tbl_Incident"."IncidentTypeID" "IncidentTypeID", "tbl_IncidentType"."Name" "IncidentTypeName", "tbl_Incident"."OfferingID" "OfferingID", "tbl_Incident"."OwnerID" "OwnerID", "Owner"."Name" "OwnerName", "tbl_Incident"."PriorityID" "PriorityID", "tbl_Incident"."StatusID" "StatusID", "tbl_IncidentStatus"."Name" "StatusName", "tbl_Incident"."Synopsis" "Synopsis", "tbl_IncidentStatus"."IsFinish" "StatusIsFinish", "tbl_Incident"."ResponseLastDate" "ResponseLastDate", "tbl_Incident"."ResponseDelay" "ResponseDelay", "tbl_Houses"."HouseAddress" "HouseAddressText", "tbl_Incident"."Flat" "Flat", case when "tbl_Houses"."HouseAddress" like '%(%' then replace( replace("tbl_Houses"."HouseAddress", ')', (case when "tbl_Incident"."Flat" is null or "tbl_Incident"."Flat" = 0 then '' else '-' end) || "tbl_Incident"."Flat" || ')'), '(', (case when "tbl_Incident"."Flat" is null or "tbl_Incident"."Flat" = '0' then '' else '-' end) || "tbl_Incident"."Flat" || '(' ) else ("tbl_Houses"."HouseAddress" || (case when "tbl_Incident"."Flat" is null or "tbl_Incident"."Flat" = '0' then '' else '-' end) || "tbl_Incident"."Flat") end "FullAddress", "tbl_Houses"."HouseRegion" "HouseRegion", (SELECT "tbl_Regions"."RegionName" "RegionName" FROM "TS"."tbl_Regions" "tbl_Regions" WHERE ("tbl_Regions"."ID" = "tbl_Houses"."HouseRegion")) "HouseRegionName" FROM "TS"."tbl_Incident" "tbl_Incident" LEFT OUTER JOIN "TS"."tbl_Contact" "Owner" ON "Owner"."ID" = "tbl_Incident"."OwnerID" LEFT OUTER JOIN "TS"."tbl_IncidentType" "tbl_IncidentType" ON "tbl_IncidentType"."ID" = "tbl_Incident"."IncidentTypeID" LEFT OUTER JOIN "TS"."tbl_IncidentStatus" "tbl_IncidentStatus" ON "tbl_IncidentStatus"."ID" = "tbl_Incident"."StatusID" LEFT OUTER JOIN "TS"."tbl_Houses" "tbl_Houses" ON "tbl_Houses"."ID" = "tbl_Incident"."HouseID" LEFT OUTER JOIN "TS"."tbl_CableType" "tbl_CableType" ON "tbl_CableType"."ID" = "tbl_Incident"."CableType" WHERE ((case when "tbl_Houses"."HouseAddress" like '%(%' then replace( replace("tbl_Houses"."HouseAddress", ')', (case when "tbl_Incident"."Flat" is null or "tbl_Incident"."Flat" = 0 then '' else '-' end) || "tbl_Incident"."Flat" || ')'), '(', (case when "tbl_Incident"."Flat" is null or "tbl_Incident"."Flat" = '0' then '' else '-' end) || "tbl_Incident"."Flat" || '(' ) else ("tbl_Houses"."HouseAddress" || (case when "tbl_Incident"."Flat" is null or "tbl_Incident"."Flat" = '0' then '' else '-' end) || "tbl_Incident"."Flat") end LIKE '%' || :pFullAddress5_U || '%')) ORDER BY 22 ASC ) WHERE ROWNUM <= 40 END OF STMT PARSE #139785163649936:c=0,e=682,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=1327010287400512
Судя по всему, параметр вообще не присваивается.
Хм. Наконец разобрался, как оно работает.
Terrasoft игнорирует любые мои параметры, фильтры, берёт код CustomSQL Column и подставляет (почему-то без UPPER()) его в WHERE, сравнивая с параметром (для которого не забывает сделать UPPER())
A OnQuickFilter срабатывает уже после того, как датасет отфильтрован.
Сейчас получилось сделать с UPPER адресами. Хотя можно уже в гриде их попробовать уменьшить.
Т.е. в Custom SQL Column дописал UPPER(...) и заработало.
А можно как-нибудь сделать, чтобы CustomSQL Column отображался без UPPER, а в фильтре оно проставлялось?
Или отображалось CustomSQL Column, а фильтровалось по другой колонке?
Здравствуйте, Ринат.
Поведение CustomSQL Column определяется бинарными файлами системы, и необходима доработка ядра для того, чтобы изменить их поведение.
Фильтровать по другой колонке действительно можно, но в таком случае Вам необходимо будет это делать непосредственно из кода, а не в запросе.
Здравствуйте Ринат,
Предлагаю другой вариант, создайте View с ID таблицы tbl_Incident, добавьте логику конкатенации. Добавьте эту View в Terrasoft (создайте сервис таблицы, укажите колонки, как в View на базе данных, на вопрос "Создать ли таблицу в БД" ответьте "Нет", проверьте таблицу создав к ней SelectQuary), добавьте таблицу View в запрос, свяжите ее с основной таблицей, после чего попробуйте использовать параметры