15.04.2006, 12:49 | #1 |
Участник
|
Класс ODBCConnection
Этот и ряд других Axapta'их класса, которые позволяют отправлять произвольный SQL-запрос и соответственно получать ответ.
Он вроде как работает в несколько раз быстрее (проверено только при сложных запросах) . У меня вопрос какие имеются подводные камни, если в отчетах для ускорения их работы использовать такие классы??? |
|
15.04.2006, 14:11 | #2 |
Участник
|
Подводных камней замечено не было. Порой - это единственное решение для быстрого построения сложных отчетов из Аксапты.
|
|
15.04.2006, 14:26 | #3 |
Administrator
|
Из моих наблюдений ...
Что неудобно / нужно помнить 1. При конструировании запроса нельзя забывать добавлять условие фильтрации компании (Аксапта ведь сама в X++ автоматически добавляет это условие). Если в системе используются виртуальные компании, то в этом случае в определенных таблицах поле dataareaid будет в себе содержать не идентификатор текущей компании, а идентификатор виртуальной компании. Конечно об этом нужно помнить только при построении запросов внутри одной компании. 2. Имя поля/таблицы в AOT вообще говоря отличается от соответствующих имен в БД. Правда это касается только таблиц/полей с именем, длиннее 30 символов (в частности у MS SQL Server) - однако такие названия встречаются. В этом случае корректнее будет за каждым названием лезть в табличку SQLDictionary - которая хранит соответствие название в АОТ названиям в БД. 3. Считать поле результата выборки (это класс ResultSet) можно только один раз и только по возрастанию порядка следования. Т.е. после считывания поля3 - поля1, 2 и 3 считать уже нельзя. Плюс возможность передвижения по курсору только вперед. Сюда же можно отнести невозможность при считывании данных обращаться по имени а не по номеру поля. 4. Ну и наконец любимая заморочка с датами. Если класс исполняется на клиенте и региональные настройки клиента отличаются от региональных настроек сервера - то для даты метод getString не прокатит - тк с точки зрения сервера это дата, однако метод getDate также не прокатит - т.к. он не сможет преобразовать серверную дату в клиентскую. Если это возможно (в Вашем случае) - я бы порекомендовал подключение через ADO. (Классы ссADO*). При их использовании пункты 3 и 4 устраняются.
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 15.04.2006 в 14:38. |
|
|
За это сообщение автора поблагодарили: mazzy (15), Dodger (1), Gustav (4), alex55 (1). |
15.04.2006, 21:54 | #4 |
Участник
|
Цитата:
Сообщение от sukhanchik
2. Имя поля/таблицы в AOT вообще говоря отличается от соответствующих имен в БД. Правда это касается только таблиц/полей с именем, длиннее 30 символов (в частности у MS SQL Server) - однако такие названия встречаются.
В этом случае корректнее будет за каждым названием лезть в табличку SQLDictionary - которая хранит соответствие название в АОТ названиям в БД. X++: dictTable.name(DbBackend::Sql);
dictTable.fieldName(fieldnum(...), DbBackend::Sql);
dictField.name(DbBackend::Sql);
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: slava (1), new-comer (1). |
16.04.2006, 11:22 | #5 |
Administrator
|
2AndyD: Ваш вариант более правильный - когда нужно строить запросы по БД текущего приложения (собственно говоря - в этой ветке так и спрашивалось).
Опираться на табличку SQLDictionary рекомендуется только в том случае - когда выборка идет из БД другого приложения Аксапты. (Очевидно - что просто в этом случае классы Dict* не помогут) Спасибо за замечание. Поблагодарить увы - не могу ибо последнее одобрение было направлено Вам. 26apcyk: Пункт 2 в моем перечне следует заменить на информацию от AndyD
__________________
Возможно сделать все. Вопрос времени |
|
17.04.2006, 06:03 | #6 |
Программатор
|
Нельзя ли выложить какой нибудь рабочий джобик, чтоб просто в ячейку А1 выгружал какое-либо значение. Просто ниразу пока что не сталкивался с ODBC но очень хочется разобраться...
|
|
17.04.2006, 08:53 | #7 |
Участник
|
Вот
X++: static void ODBCConnection2Excel(Args _args) { LoginProperty LP = new LoginProperty(); OdbcConnection myConnection; Statement myStatement; ResultSet myResult; DictTable dictTable = new DictTable(tableNum(InventTable)); ComExcelDocument_Ru Excel = new ComExcelDocument_Ru(); Com Doc; Com App; Com Worksheet; Com Range; int i = 1; ; Excel.newFile("", false); doc = Excel.getComDocument(); App = doc.Application(); Worksheet = App.ActiveSheet(); LP.setDSN("Axapta"); /* LP.setUsername(""); // Если необходимо - устанавливаем имя и пароль для подключения LP.setPassword("");*/ try { myConnection = new OdbcConnection(LP); } catch { info("Check username/password."); return; } myStatement = myConnection.createStatement(); myResult = myStatement.executeQuery( strfmt("SELECT %3, %4 FROM %1 WHERE DataAreaId = '%2'", dictTable.name(DBBackend::Sql), curext(), dictTable.fieldName(fieldnum(InventTable, ItemId), DBBackend::Sql), dictTable.fieldName(fieldnum(InventTable, ItemName), DBBackend::Sql))); Range = Worksheet.Range("A1"); Range.NumberFormat("@"); Range.Value2(dictTable.fieldObject(fieldnum(InventTable, ItemId)).label()); Range = Worksheet.Range("B1"); Range.NumberFormat("@"); Range.Value2(dictTable.fieldObject(fieldnum(InventTable, ItemName)).label()); while (myResult.next()) { Range = Worksheet.Range(ComExcelDocument_Ru::numToNameCell(1, i+1)); Range.NumberFormat("@"); Range.Value2(myResult.getString(1)); Range = Worksheet.Range(ComExcelDocument_Ru::numToNameCell(2, i+1)); Range.NumberFormat("@"); Range.Value2(myResult.getString(2)); if (i > 100) break; i++; } Range = Worksheet.Range("A1", "B1"); Range = Range.EntireColumn(); Range.AutoFit(); Excel.visible(true); }
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: Sada (1). |
17.04.2006, 09:18 | #8 |
Программатор
|
2AndyD
Спасибо большое! С уважением - Sada... |
|
19.04.2006, 20:27 | #9 |
Moderator
|
Цитата:
Сообщение от sukhanchik
Если это возможно (в Вашем случае) - я бы порекомендовал подключение через ADO. (Классы ссADO*).
"Примеры подключения различных Баз Данных через ADO" (в том числе через драйверы ODBC) http://www.webmasterpro.com.ua/news339.html Цитата:
Данный материал содержит примеры создания строк ADO connection для различных типов часто используемых Баз Данных, например: ODBC DSN, ODBC DSN-Less, OLE DB Provider, MS Remote, Oracle, Excel, FoxPro и т.д.
Цитата:
Примечание: You can also open an Excel spreadsheet using the "OLE DB Provider for Microsoft Jet"
oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=somepathexpenses.xls;" & _ "Extended Properties=""Excel 8.0;HDR=Yes;"";" Where "HDR=Yes" means that there is a header row in the cell range (or named range), so the provider will not include the first row of the selection into the recordset. If "HDR=No", then the provider will include the first row of the cell range (or named ranged) into the recordset. "How To Open a Secured Access Database in ADO Through OLE DB" http://support.microsoft.com/kb/q191754/ P.S. Если кто-то будет играться с темой "ADO+Excel", то вот в дополнение крайне полезная ссылка на ветку "Быстрый Excel": http://www.axforum.info/forums/showt...2677#post22677 , в которой упоминается тема "How To Use ADO with Excel Data from Visual Basic or VBA": http://support.microsoft.com/kb/q257819/ Последний раз редактировалось Gustav; 20.04.2006 в 12:50. |
|
|
За это сообщение автора поблагодарили: sukhanchik (1). |
20.04.2006, 00:02 | #10 |
Administrator
|
Строки ADO легко генерить, создав файлик *.udl и 2 раза по нему щелкнув. Откроется некое окошко - конструктор строк подключения. Результаты работы конструктора сохранятся в тектовом виде в файлике (кстати вместо строки подключения можно задавать путь к этому файлику).
Правда есть одно но. В любимом нами драйвере Jet указаны только параметры подключения к аксессной базе. Однако - достучаться вообще говоря можно также к Excel, DBF, DB (полный список можно увидеть - при попытке в Access (.mdb) прилинковать табличку. Jet ведь вырос ногами из DAO - а там на строку подключения легко глянуть - заглянув в хелп аксессный по свойству Connect у объекта TableDef (можно даже русский, по Access 97). Другое дело, что Extended Parameters очевидно там (аксессном хелпе) не описаны. И за их нарытие - Вам спасибо.
__________________
Возможно сделать все. Вопрос времени |
|
18.11.2008, 18:37 | #11 |
Moderator
|
узелок на память
Цитата:
Сообщение от sukhanchik
4. Ну и наконец любимая заморочка с датами. Если класс исполняется на клиенте и региональные настройки клиента отличаются от региональных настроек сервера - то для даты метод getString не прокатит - тк с точки зрения сервера это дата, однако метод getDate также не прокатит - т.к. он не сможет преобразовать серверную дату в клиентскую.
X++: Statement S; ResultSet resultSet; TransDate tDate; ...... resultSet = S.executeQuery( "SELECT TO_CHAR(TransDate, 'DD.MM.YYYY') AS td FROM Table1"); while (resultSet.next()) { tDate = str2date(resultSet.getString(1), 123); ...... } |
|