Здравствуйте. Такая проблема: не фильтруется датасет по CustomSQLColumn.
Попробовал сделать через OnQuickFilter, как советовали в https://community.terrasoft.ru/blogs/4397 , тоже не работает.
Как заставить его работать? В таблице дублировать данные очень нежелательно.
Спасибо.
Нравится
Здравствуйте, Ринат!
Если он пустой, значит, он фильтруется. Просто не совпадают значения и содержимое.
Если бы он не фильтровался - тогда бы просто всегда вверху было первое значение.
Рекомендую Вам просто вывести рядом значение, по которому фильтруете, и значение датасета, которое хотите отфильтровать. Вероятнее всего, несовпадение синтаксиса.
Как альтернативный вариант, оберните CustomSQLColumn в subselect. Есть такая небольшая недокументированная фича. :) Т.е. создаете в SelectQuery подзапрос по таблице, у которой по любому есть только одна запись (лучше создать такую и добавить в нее одну запись). Потом в подзапросе добавляете CustomSQLColumn и реализуете в ней все, что хотите. И все. Далее в ядре подзапрос успешно "оборачивается" и при выполнении сортировки, и фильтраций, и при использовании итогов по нему. Можете проверить этот вариант (просто не во всех версиях он работает).
Через subquery не получилось.
SelectQuery формируется правильно, но по-моему параметр не передаётся в запрос
[sql]
...
WHERE
("tbl_Houses"."HouseAddress" || "tbl_Incident"."Flat" like '%' || :pFullAddress_U || '%')
[/sql]
В террасофте параметр FullAddress создан, значение ему присваивается.
Вызывается так:
[javascript]
function grdDataOnQuickFilter(DataGrid, DataField, Value, QuickFilterLikeType, DoFilter, DoQuickFilter) {
debugger;
if(DataField.Name == 'FullAddress')
{
var Dataset = DataGrid.DatasetLink.Dataset;
ApplyDatasetFilter(Dataset, 'FullAddress', Value, true);
[/javascript]
Для того, чтобы фильтр отработал, необходимо выполнить запрос, то есть, обновить датасет. То есть, закрыть его и открыть заново.
То есть, после
[javascript]
var Dataset = DataGrid.DatasetLink.Dataset;
ApplyDatasetFilter(Dataset, 'FullAddress', Value, true);
[/javascript]
добавить
[javascript]
Dataset.Close();
Dataset.Open();
[/javascript]
Всё равно пусто.
Копирую сформированный SelectQuery из дебага, подставляю на место :pFullAddress реальный адрес 'Лермонтова', SelectQuery работает.
Может, мне Пользовательский SQL-фильтр переписать? Как-нибудь параметр по-другому передавать?
Сейчас он такой:
[sql]
UPPER("tbl_Houses"."HouseAddress" || "tbl_Incident"."Flat") like '%' || :pFullAddress_U || '%'
[/sql]
Ринат, рекомендую Вам посмотреть профайлером.
Что касается фильтра, рекомендую Вам попробовать следующую конструкцию:
[sql]
UPPER("tbl_Houses"."HouseAddress" || "tbl_Incident"."Flat") LIKE '%' + :pFullAddress_U + '%'
[/sql]
А что в итоге идет в базу данных? Пробовали смотреть запросы профайлером?
Что касается объединения строк, Можете попробовать так:
[sql]
CONCAT(CONCAT('%', :pFullAddress_U)), '%')
[/sql]
Не пойму, зачем Вы фильтр накладываете на OnQuickFilter, т.е. после того, как пользователь в гриде уже применил быстрый фильтр. Т.е. датасет уже открылся и уже что-то делать поздно. По моему, мы не туда "копаем". Можете описать задачу детальнее?
Есть такой вот Пользовательский SQL-фильтр в sq_Incidents:
[sql]
UPPER("tbl_Houses"."HouseAddress" || "tbl_Incident"."Flat") LIKE '%' || :pFullAddress_U || '%'
[/sql]
В датасет он попадает, но датасет по нему не фильтруется, т.к. не всё так просто с этим фильртом, он берёт "адрес дома" из объединённой таблицы и конкатенирует с "квартирой" из основной.
(Сам инцидент привязывается к ID дома, на котором он произошёл, но также важен поиск по полному адресу)
Есть параметр FullAddress (:pFullAddress).
Наверное, всё же придётся дублировать данные в таблице инцидентов...
Просто в сабже Вы писали о CustomSQLColumn и я решил, что Вам нужна возможность фильтрации по такой колонке. Ладно.
1. Согласно Вашего sql-запроса параметр должен называться FullAddress_U, а не FullAddress. Наша engine потом сама добавит при анализе запроса :p и получится :pFullAddress_U.
2. В SQLMonitor-е как запрос целиком отображается (вместе с параметрами и их значениями)?
Вот отрывок трейс-файла оракл, назвал параметр FullAddress_U без :p
[sql]
*** 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
[/sql]
Судя по всему, параметр вообще не присваивается.
Хм. Наконец разобрался, как оно работает.
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 в запрос, свяжите ее с основной таблицей, после чего попробуйте использовать параметры