|
![]() |
#1 |
Участник
|
и еще одно... уж, извините.
знающим java будет понятно. мне всегда режет глаз сложение строк. в старых java vm это приводит к дикой сборке мусора. См. холивары на тему StringBuilder vs конкатенация строк. в Аксапте до версии 2012 включительно используется очень старый джавовский движок. вообще говоря, если уж работаете со строками хоть каким способом, то лучше избегать массового сложения строк, а использовать strfmt. еще один повод все перевести в объекты, а строку генерировать только в самом конце ) |
|
|
За это сообщение автора поблагодарили: Ace of Database (2). |
![]() |
#2 |
Дмитрий Ерин
|
Нууу... это ж котлин, там действительно всё красиво
![]() Но имеем то, что имеем (Х++)... Про конкатенацию почему-то ожидал вопроса) Мне тоже режет. Хотя какое-нибудь "((%1.%4==%2.%5)||(%2.%6!=%3.%5))" режет не меньше), но холиварить не стану - я тоже против длинных сложений. В моем случае перевесил критерий переносимости кода (Java -> X++ -> etc.). Речь ведь о прототипе. Цитата:
Цитата:
Но тут я вижу немного другое назначение - улучшить читабельность кода, когда все-таки (так сложились звезды) запрос конструируется программно, и потом может подвергаться доработкам. При этом не важно, как он формируется и хранится внутри - текстом или объектами (в примере ниже - на выходе получаем QueryRun). Вот, для затравки, первые наброски: X++: queryRun = SimpleQueryBuilder::newQuery(). // здесь параметром вполне может выступить querystr(MyAOTquery) select (tablenum(CustTable)). groupBy (fieldnum(CustTable, AccountNum)). groupBy (fieldnum(CustTable, PartyId)). join (tablenum(CustTransOpen)). relations (true). sumField (fieldnum(CustTransOpen, AmountCur)). parent(). join (tablenum(CustGroup)). relations (true). mode (JoinMode::ExistsJoin). range (fieldnum(CustGroup, PaymIdType), paymIdType). queryRun(); while (queryRun.next()) { ... } Удобно ли? Или те же буквы, только в профиль?) |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
![]() |
#3 |
Участник
|
хотел удержаться... но не удержался...
обещал не использовать термин "программистский подход"... Про программистский подход, программистское мышление и стереотипы но ту тему тоже создал некий пользователь Ruff ))))) что хочу сказать. улучшить читабельность кода - хорошая задача. для учебных целей. а в промышленном внедрении нафиг не нужная. проект улучшить читабельность кода - своеобразный мастурбатор для программистов. да, удовольствие доставляет. результат - крайне сомнительный. 1. писать запросы в коде, со всеми полям, join'ами, условиями на поля... само по себе неблагодарное дело. программист тратит свое время не на "читабельность", а на то, чтобы вспомнить обязательные таблицы в join, обязательные связи между таблицами, обязательные поля группировок, непустые поля... пример? до 2009 включительно номенклатура состоит из 8 таблиц. 3 из которых обязательны, а одна из них должна джойнится три раза с разными условиями. навскидку запрос напишите? а в 2012 и дальше ввели общие для всех компаний продукты и вместо номенклатуры "используемые продукты" по отдельным компаниям. там порядка 20 таблиц. навскидку запрос напишите? "читабельность кода" - очень малая часть трудозатрат. ![]() нужны пресеты для работы с логическими сущностями. 2. все становится намного хуже, если идет работа с внешними системами. в 1С например, таблицы и поля имеют числовые идентификаторы вместо названий. а в SAP часто используются немецкие названия полей или еще хуже - английская транскрипция немецких терминов. читабельность кода? ха-ха-ха-ха!!!! нужны удобные алиасы для полей и таблиц (особенно внешних). нужны пресеты для сущностей вместо обращения к отдельным таблицам например, сущность "номенклатура" - состоит из... с сущностью "номенклатура" можно работать так то... 3. во внешних системах и внешних программах часто используются дефиниции таблиц и связей в json- или xml-файлах. (см. например, java-проект Hibernate, http://devcolibri.com/1394 ). использование таких дефиниций на порядки более упросит жизнь программиста, нежели пресловутая "читаемость кода" 4. реально упросить жизнь программисту можно одним способом - снизить сложность используемых программистом сущностей. другими словами, что нужно: = чтение уже готовых дефиниций таблиц и связей в объект = работа с пресетами сущностей, вместо работы с отдельными нормализованными(!) таблицами (как целиком, так и с частью запроса. см. например, InventSum::initQueryFrom) = пресет должен подсказывать программисту какие компоненты пресета являются обязательными для заполнения по бизнес-логике (поля, условия, группировки, агрегатные функции) = пресет должен подсказывать программисту когда он нарушает целостность данных из-за отсутствующего компонента запроса (группировка, условие, агрегатная функция) = пресет должен подсказывать программисту когда он может нарушить целостность данных из-за возможного дублирования уникальных полей далее нужен код типа: X++: Query q1 = new QueryBuilder::constructFromPreset(mySuperPreset1); Query q2 = new QueryBuilder::addFromPreset(q1, mySuperPreset2); тем не менее, как я уже говорил подобные DML - очень хорошая учебная задача. своеобразный "ослиный мостик". все такое делают. но на практике программисту проще написать str s = strfmt("select %1 from %2 %3 %4 where %5", fields, tableWithAlias, orders, groups, whereclause); чем разбираться с очередным билдером, который занимается только "читабельностью кода" ))) Последний раз редактировалось mazzy; 27.01.2016 в 12:17. |
|
![]() |
#4 |
Участник
|
Цитата:
Если это умозрительная конструкция, хотелось бы в этой фразе заменить "на практике" на "в теории". Последний раз редактировалось belugin; 04.02.2016 в 14:07. |
|
![]() |
#5 |
Участник
|
Цитата:
Цитата:
Сообщение от документация
...
A data entity is an abstraction from the physical implementation of database tables. For example, in normalized tables, a lot of the data for each customer might be stored in a customer table, and then the rest might be spread across a small set of related tables. In this case, the data entity for the customer concept appears as one de-normalized view, in which each row contains all the data from the customer table and its related tables. A data entity encapsulates a business concept into a format that makes development and integration easier. The abstracted nature of a data entity can simplify application development and customization. Later, the abstraction also insulates application code from the inevitable churn of the physical tables from version to version of Microsoft Dynamics AX. To summarize: Data entity provides conceptual abstraction and encapsulation (de-normalized view) of underlying table schemas to represent key data concepts and functionalities. ... Последний раз редактировалось belugin; 04.02.2016 в 14:06. Причина: Ссылка на более концептуальный материал |
|
|
За это сообщение автора поблагодарили: Ruff (2). |
![]() |
#6 |
Участник
|
Цитата:
Сообщение от Ruff
![]() Вот, для затравки, первые наброски:
X++: queryRun = SimpleQueryBuilder::newQuery(). // здесь параметром вполне может выступить querystr(MyAOTquery) select (tablenum(CustTable)). groupBy (fieldnum(CustTable, AccountNum)). groupBy (fieldnum(CustTable, PartyId)). join (tablenum(CustTransOpen)). relations (true). sumField (fieldnum(CustTransOpen, AmountCur)). parent(). join (tablenum(CustGroup)). relations (true). mode (JoinMode::ExistsJoin). range (fieldnum(CustGroup, PaymIdType), paymIdType). queryRun(); while (queryRun.next()) { ... } Удобно ли? Или те же буквы, только в профиль?) X++: mode (JoinMode::ExistsJoin). и не поставлен на открытые проводки, которые вполне штатно могут отсутствовать. почему выбираются клиенты только с открытыми проводками? это логика такая? или это логическая ошибка? почему в запросе читаются только открытые проводки без самих проводок? открытые проводки сами по себе используются крайне редко, поскольку это логически "подчиненная таблица". отсутствие проводок в запросе - это логическая ошибка или так задумано? что вы дальше будете делать с этой несопоставленной суммой по всему клиенту? прекрасная ошибка - суммирование AmountCur без группировки по валютам. запрос вернет сумму рублей с долларами, еврами, гривнами, тугриками и остальными валютами. правило: если выполняется агрегирование по AmounCur, то группировка по валютам является обязательной. именно такая информация и должна присутствовать в пресете. подумайте о таких логических взаимосвязях только один раз - при создании пресета, а потом пусть программа думает и предупреждает. тогда и будет "удобно". )))) упростите именно логическую часть, упростите бизнес-логику для программиста. программисты даже купят у вас такое решение ) а упрощение синтаксиса... ну, да... оно конечно тоже приятно. ))) ========================== добавил, подумав над запросом: PaymIdType есть в группе, а есть в самом клиенте. кроме того, он есть в paymMode, который присутствует в проводке. мне кажется, что фильтрация по полю PaymIdType в группе - всегда логически ошибочна. мне кажется, что нет случаев, когда фильтрация по полю PaymIdType в группе была бы логически оправдана. да, я понимаю, что запрос написан "для примера". но получился отличный пример реальных трудозатрат - время программиста тратится на связи между таблицами и на логику, а не на синтаксис. упростите логику. дайте возможность написать логику один раз, а потом массово использовать. тогда проект имеет и промышленную ценность. а упрощение синтаксиса... ну, да... оно конечно тоже приятно. ))) ================= трудозатраты: время последней правки 13:00 - время создания готового поста с первоначальным текстом 12:25 ~= 0:35 минут потрачено на обдумывание логики запроса сам пост написан минуты за 2 ))) и это очень типичное соотношение трудозатрат между логикой и синтаксисом. Последний раз редактировалось mazzy; 27.01.2016 в 13:02. Причина: добавил про PaymIdType и время |
|
Теги |
download, t-sql, готовый пример, запросы, пример |
|
|