"Ambiguous field name between table" как обойти?

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

Ответить
mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

"Ambiguous field name between table" как обойти?

Сообщение mdfv » 03 июл 2007, 17:22

Вот сборный из нескольких таблиц запрос примерно такого вида.

Код: Выделить всё

select 
t1.pole1,
t2.pole2
from
table1 t1
left outer join table2 t2
  on (t1.t2id=t2.id)
Работает замечательно до тех пока пользователь не включит фильтрацию(серверная) по этим полям.
А проблема в том что в этих таблицах есть поля с одинаковыми между собой именами. И сервер как бы не знает чье поле фильтровать.

Вот вопрос состоит в том как обойти псевдоним таблицы?,
Или можно ли узнать у датасета полное имя поляны с псевдонимом таблицы, (по сути что-то типа правильного origin-а )?
ЗЫ. FIBPlus 6.5

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 03 июл 2007, 18:07

Не совсем понял выдвинутые тобой ограничения. Кто чего фильтрует.
Последний раз редактировалось WildSery 03 июл 2007, 18:46, всего редактировалось 1 раз.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 03 июл 2007, 18:08

При написании запросов пользоваться алиасами таблиц. Хотя... мож FIBPlus за программиста уже и кушать научился...

Slavik
Сообщения: 115
Зарегистрирован: 17 янв 2007, 11:52

Re: "Ambiguous field name between table" как обой

Сообщение Slavik » 03 июл 2007, 18:44

mdfv писал(а):Или можно ли узнать у датасета полное имя поляны с псевдонимом таблицы, (по сути что-то типа правильного origin-а )?
Свойство TField.Origin можно только назначить. Тогда (возможно) оно и будет подхватываться фильтратором. А вот автоматически его можно получить скорее всего только через распарсивание запроса. Может имеет смысл обратиться в тех.поддержку FIBPlus?

Сам я автоматам доверяю только локальную фильтрацию, ибо запросы, которые надо давать фильтровать пользователю, у меня редко сводяться к простой выборке из одной таблицы, а полей с одинаковыми стандартными наименованиями (типа ID, CODE, TITLE, NOTE...) полно.

P.S. Встречал довольно большие проекты (порядка 1000 таблиц), где все имена полей были уникальными (в них использовались префиксы из сокращённого названия таблицы). Но разбирать такое мне лично очень трудно, да и имена сильно удлиняются...
Последний раз редактировалось Slavik 03 июл 2007, 18:49, всего редактировалось 1 раз.

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 03 июл 2007, 18:45

У пользователя есть стандартная формочка для ввода фильтра по полям датасета. Внутри этой формы тупо берется свойство каждого видимого поля датасета DisplayName и его имя FieldName, пользователю соответсвенно показывается понятное описание полянки, а внутри оно соответсвует имени поля из датасета, сюда и прикручивается введенное пользователем условие,
причем форма универсальная для всех датасетов, кроме того содержимое запроса заранее неизвестно.
формируется серверная фильтрация потом через
TpFibDataset.Conditions.AddCondition и
TpFibDataset.ApplyConditions.
Так вот проблема в том и есть что надо узнать псевдоним таблицы указанный в запросе для каждого поля, парсить вручную запрос не очень хочется, думается есть более красивое решение.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 03 июл 2007, 18:45

Merlin писал(а):При написании запросов пользоваться алиасами таблиц. Хотя... мож FIBPlus за программиста уже и кушать научился...
Судя по примеру, использует.
Я из его поста подумал, что у него в гриде два поля NAME, к примеру, получается, и он в WHERE хочет AND NAME='...' добавить, не зная, из какого алиаса оно берётся.
В предыдущем посте я ступил - WHERE по алиасу не понимает, только GROUP и ORDER.

Slavik
Сообщения: 115
Зарегистрирован: 17 янв 2007, 11:52

Сообщение Slavik » 03 июл 2007, 18:58

mdfv писал(а):содержимое запроса заранее неизвестно.
Свойство FIBDataset.SelectSQL переписывается? или задаётся в дизайне и стандартной форме-фильтру подсовывается FIBDataset? Если задаётся в дизайне, то в том же дизайне ты можешь задать свойства TField.Origin каждому полю (если надо) и в AddCondition пользовать именно его.

В общем, суть сводится к тому, что так или иначе где-то рядом с самим запросом надо хранить Origin полей. То ли в TField.Origin, то ли в базе (зависит от того где храняться сами запросы).

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 03 июл 2007, 19:12

WildSery писал(а):Судя по примеру, использует.
Я из его поста подумал, что у него в гриде два поля NAME, к примеру, получается, и он в WHERE хочет AND NAME='...' добавить, не зная, из какого алиаса оно берётся.
А. Тогда точно в техподдержку. Не знаю, как нынче выглядит реализация Conditions в плюсАх, в прототипе было примерно так

Код: Выделить всё

  TCSellerCnd:=TCondClass.Create(Self);
  TCSellerCnd.Tip:=RecKod;
  TCSellerCnd.FieldNames:='TC.Seller';
  TCSellerCnd.SrcFields:='Code';
...
тоиссь, прописывалось ручками и поле в таргет-запросе и поле в запросе-заполняторе (для этого типа условия). Но там наверняка на всё какой-нить вижуально-мышковый Кудесник предусмотрен :wink:

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 03 июл 2007, 19:21

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

Если б все задавалось в дизайне, то проблема бы решилась быстро.
Решение у проблемы есть, т.к. у фиба есть такая не менее полезная вещь как репозиторий полей, где полянки хранятся вместе со своими таблицами, и именами для отображения в гриде.
И каким-то образом датасет понимает какое поле в соответствии с алиасом таблицы куда подставить.
Видимо придется поглубже копнуть исходники фибовские, чтобы оттуда выудить данный метод.

Slavik
Сообщения: 115
Зарегистрирован: 17 янв 2007, 11:52

Сообщение Slavik » 03 июл 2007, 20:04

mdfv писал(а):Решение у проблемы есть, т.к. у фиба есть такая не менее полезная вещь как репозиторий полей, где полянки хранятся вместе со своими таблицами, и именами для отображения в гриде.
И каким-то образом датасет понимает какое поле в соответствии с алиасом таблицы куда подставить.
Видимо придется поглубже копнуть исходники фибовские, чтобы оттуда выудить данный метод.
Всё достаточно ясно описано в Руководстве разработчика FIBPlus. Из него же видно, что репозитарий полей в FIBPlus несколько "ущербный", т.к. описания полей привязываются к именам таблиц, а не к DataSet'ам, что ограничивает гибкость, прибивая настройку полей для каждого DataSet'а, но получая универсальное описание поля таблицы в одной записи. Там же можно сохранять дополнительно и свои настройки полей (например, тот же Origin).

Очень неудобно, что алиасы полей в FIBPlus свалили в одну кучу. У меня, например, в одном запросе алиас CNT может соответствовать одному выражению, а другом - совершенно другому. И выдумывать уникальные алиасы по-моему слишком муторно. Легче прикрутить свою табличку с настройками полей для каждого DataSet'а отдельно.

Кстати, а как быть, если в запросе используется group by? Тут уж, хочешь не хочешь, а придётся ваять собственный репозитарий полей, в котором должен быть ещё и признак группируемости Field.Origin: какое надо в секцию where, а какое в having?

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 03 июл 2007, 21:11

Ну до group by дело думаю не дойдет пока. Стараюсь таких не делать вещей. Это уже политический вопрос. В программе пользователю нужно видеть только в основном простые таблички для редактирования, максимум с джойнами вместо лукапов живых, которые удачно фильтруются на сервере.
А во всяких сложных формах лучше тогда применить локальную фильтрацию. Или сделать менее универсальный механизм, но более заточенный под такие конкретные вещи(что собственно и делалось).

Сейчас программулина больше похожа на эвакуированный на Урал завод в 41 году. Крыши и стен нету, а уже во всю кует оружие победы. Постепенно обрастая функционалом, но без излишеств.
На уровне алгоритма работы заложено, что вообще вся обработка делается по одной кнопке(и в основном на сервере) и ручное вмешательство пользователя должно быть в исключительных случаях.
А городить огород на это из своих дополнительных табличек, нету времени. Хотя на начальном этапе задумывался над этим, но раз в фибах уже есть более менее подходящее, то тратить время, на велосипед хоть и более удобный пока не стоит.

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 03 июл 2007, 22:13

Всем спасибо.
Нашел то что нужно.
У фибдатасета есть метод с говорящим названием TableAliasForField.
Осталось его прикрутить к имени поля и фокус удался.

Еще есть метод GetFieldOrigin хотя он странновато работает.
если у таблицы нет псевдонима, то в оригине показывается полная связка таблица.поле, а если есть алиас, то только имя поля.

Slavik
Сообщения: 115
Зарегистрирован: 17 янв 2007, 11:52

Сообщение Slavik » 04 июл 2007, 09:58

А если это выражение или поле из подзапроса, то и вовсе ничего не показывает :(

Ответить