AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 24.01.2019, 07:36   #1  
TalgatAb is offline
TalgatAb
Участник
 
18 / 11 (1) +
Регистрация: 31.01.2018
Call SQL Stored Procedure формирование отчета
Кто нибудь сталкивался с формированием отчетов с помощью хранимой процедуры SQL. Или данный метод противоречить с политикой Axapta. Здесь столкнулся с одной проблемой. У меня запускается данный отчет, а у пользователя выдается ошибка. Вообще стоит работать с подобным методом, вызов хранимой процедуры через SqlClient и формировать отчеты?


X++:
#AviFiles
//Алгоритм заполнения описывается не в run(), а в fillDocument()
protected void fillDocument()
{
    System.Data.SqlClient.SqlConnection cnn;
    System.Data.SqlClient.SqlCommand    cmd;
    System.Exception                    e;
    System.Data.SqlClient.SqlDataReader sdr;

    System.Data.SqlClient.SqlParameterCollection parameterCollection;

    SysSQLSystemInfo     systemInfo = SysSQLSystemInfo::construct();
    CodeAccessPermission perm2 = new InteropPermission(InteropKind::ClrInterop);

    str             sqlStr, beg_date, end_date;

    SqlSystem       sqlSystem;
    SqlStatementExecutePermission  sqlPermission;

    //
    System.Data.DataTable   stockTable;
    System.Data.DataRow     row;
    System.Data.DataRowCollection rows;

    Counter                 counter;
    int                     i;

    str                     picName;
    boolean                 bPrint;
    container               con, conDim, conValues;

    ItemId           itemId;
    ItemName         itemName;
    UnitId           unitId;
    str              itemType, inventPicName;
    str              dimension5, dimension2, dimension2_;
    InventSerialId   inventSerialId;
    InventGtdId_RU   inventGtdId_RU;
    WMSLocationId    wmsLocationId;
    LedgerAccount    account, accountOffset;
    TransDate        transDate, deliveryDate;

    CLRObject         clrObj;
    InteropPermission perm;
    System.Exception  ex;

    boolean           found;

;

    excelWorksheet.range('Company').value2(CompanyInfo::find().Name);
    excelWorksheet.range('dates').value2(strfmt("%1 - %2", fromDate, toDate));

    //Инициация буфера отчета. В него помещаются строки отчета
    excelWorksheet.bufferStart();

    //this.progressInit("Реестр платежей", SysQuery::countTotal(queryRun), #AviTransfer);
    this.progressInit("Выгрузка в excel", 10000, #AviTransfer);

    stockTable = this.CreateTable();
    rows = stockTable.get_Rows();

    sqlStr = "dbo.ALA_InventTransRest";
    beg_date = date2Str(fromDate, 321, DateDay::Digits2, DateSeparator::None, DateMonth::Digits2, DateSeparator::None, DateYear::Digits4);
    end_date = date2Str(toDate, 321, DateDay::Digits2, DateSeparator::None, DateMonth::Digits2, DateSeparator::None, DateYear::Digits4);

    cnn = new System.Data.SqlClient.SqlConnection(
          strfmt("Data Source=%1;Initial Catalog=%2;Integrated Security=True;Connection Timeout=120",
                  systemInfo.getLoginServer(), systemInfo.getloginDatabase()));
    cmd = cnn.CreateCommand();
    cmd.set_CommandText(sqlStr);
    cmd.set_CommandType(System.Data.CommandType::StoredProcedure);

    parameterCollection = cmd.get_Parameters();
    parameterCollection.AddWithValue("@beg_date", beg_date);
    parameterCollection.AddWithValue("@end_date", end_date);
    parameterCollection.AddWithValue("@item", item);

    try {
        cnn.Open();

        sdr = cmd.ExecuteReader();
        try {
            while (sdr.Read()) {
                counter++;
                account = sdr.GetString(0);
                accountOffset = sdr.GetString(1);
                itemId = sdr.GetString(2);
                itemName = sdr.GetString(3);
                unitId = sdr.GetString(4);
                itemType = sdr.GetString(5);
                inventLocationId = sdr.GetString(6);
                wmsLocationId = sdr.GetString(7);
                inventSerialId = sdr.GetString(8);
                inventPIC = sdr.GetString(9);
                inventPicName = sdr.GetString(10);
                dimension5 = sdr.GetString(11);
                dimension2_ = sdr.GetString(12);
                deliveryDate = sdr.GetDateTime(13);
                dimension2 = sdr.GetString(14);
                inventGtdId_RU = sdr.GetString(15);
                sQty = sdr.GetDecimal(16);
                sAmount = sdr.GetDecimal(17);
                iQty = sdr.GetDecimal(18);
                iAmount = sdr.GetDecimal(19);
                oQty = sdr.GetDecimal(20);
                oAmount = sdr.GetDecimal(21);
                eQty = sdr.GetDecimal(22);
                eAmount = sdr.GetDecimal(23);
                transDate = sdr.GetDateTime(24);
                conValues = [counter,
                    account,
                    accountOffset,
                    itemId,
                    itemName,
                    unitId,
                    itemType,
                    inventLocationId,
                    wmsLocationId,
                    inventSerialId,
                    dimension5,
                    dimension2_,
                    deliveryDate,
                    dimension2,
                    inventGtdId_RU,
                    inventPIC,
                    inventPicName,
                    sQty,
                    sAmount,
                    iQty,
                    iAmount,
                    oQty,
                    oAmount,
                    eQty,
                    eAmount,
                    transDate];

                excelWorksheet.bufferAddLine(conValues, 'Data_Body', 'Data_Bottom');
                if ((counter > 1) && (counter mod 300 == 0)) {
                    i = i > 0 ? 8 + counter - 300 : 8;
                    excelWorksheet.bufferPost(strfmt("A%1", i), connull());
                    //Инициация буфера отчета. В него помещаются строки отчета
                    excelWorksheet.bufferStart();
                }
                this.parmProgress().incCount();
            }
            sdr.Dispose();

            excelWorksheet.bufferPost(strfmt("A%1", 7 + counter - (counter mod 300)), ['Data_Body','Data_Bottom']);
        } catch (Exception::Error) {
            info("Caught 'Exception::Error'.");
        } catch (Exception::CLRError) {
            perm = new InteropPermission(InteropKind::ClrInterop);
            if (perm == null) {
                return;
            }
            perm.assert();

            e = ClrInterop::getLastException();
            if (e != null) {
                e = e.get_InnerException();
                if (e != null) {
                    info(e.ToString());
                }
            }
            //CodeAccessPermission::revertAssert();
        }

    } catch (Exception::CLRError) {
        ex = ClrInterop::getLastException();
        while(ex)
        {
            error(ex.get_Message());
            ex = ex.get_InnerException();
        }
        if (sdr != null)
            sdr.Dispose();
    }

    if (cnn.get_State() == System.Data.ConnectionState::Open)
       cnn.Close();

    CodeAccessPermission::revertAssert();
}
Старый 24.01.2019, 13:07   #2  
Maximin is offline
Maximin
NavAx
NavAx Club
 
404 / 330 (12) ++++++
Регистрация: 09.10.2002
Адрес: Москва
Ну, как тебе сказать...
Вот ты и наткнулся на первую проблему - юзерам надо раздавать права еще и на SQL.
Вторая: код бизнес-логики "размазывается" между сущностями - еще одни проблемы при развертывании и поддержке. Нужна экспертиза по SQL хранимкам и DBA нужен не совсем деревянный.
Конечно, это противоречит единому стилю и духу AX. Она ж для того и писана, чтобы вот это вот все выкинуть и взять единую среду. Вопрос баланса и возможностей. Если минусы нивелируются плюсами (обычный плюс - скорость), то почему бы и нет?
Вон в соседней теме временные таблицы запилили в 2009. Я бы вот поостерегся такое пилить клиенту, работая в консалтинге. А сидя на самом клиенте - может, и сделал бы, если других путей не очень-то. Еще и плюс можно поиметь в виде незаменимости, ибо разобраться в таком - надо ж не средним специалистом в AX быть...
__________________
Жизнь прекрасна! Если, конечно, правильно подобрать антидепрессанты...

Последний раз редактировалось Maximin; 24.01.2019 в 13:09.
За это сообщение автора поблагодарили: ax_mct (2).
Старый 24.01.2019, 14:11   #3  
ax_mct is offline
ax_mct
Участник
Аватар для ax_mct
 
2,392 / 912 (35) +++++++
Регистрация: 10.10.2005
Адрес: Westlands
В коде бардак с .assert() как минимум для SqlStatementExecutePermission.
То есть имеет смысл убедиться в том что все permisson.assert() вызываются до вызовов.
Старый 25.01.2019, 11:36   #4  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
524 / 245 (10) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Если вы работаете прямо на сервере, то обычным пользователям не дана такая роскошь.
Измените свой код, чтобы он вызывался на стороне сервера. Т.е. либо RunOn = Server, либо
X++:
public server static void ...
Тогда и пользователям будет счастье.
__________________
Незаменимых людей нет. Но и в отпуск мы тебя не отпустим. © Начальник
За это сообщение автора поблагодарили: TalgatAb (1).
Старый 25.01.2019, 12:22   #5  
TalgatAb is offline
TalgatAb
Участник
 
18 / 11 (1) +
Регистрация: 31.01.2018
Спасибо за рекомендации, как раз рассматриваю подобный метод:

X++:
server static ResultSet executeQuery(str sql, Connection connection = new Connection())
{
    SqlStatementExecutePermission   sqlPerm;
    Statement                       statement;
    ResultSet                       resultSet;
    ;

    sqlPerm = new SqlStatementExecutePermission(sql);
    sqlPerm.assert();

    statement = connection.createStatement();
    resultSet = statement.executeQuery(sql);

    CodeAccessPermission::revertAssert();

    return resultSet;
}
Хотя, SQL запросы все-таки, придется перевести на X++ select-ы...
За это сообщение автора поблагодарили: ax_mct (1).
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Формирование авансового отчета Аксапта 2009 Brosha DAX: Функционал 3 21.12.2016 13:57
emeadaxsupport: How to perform a data center change (change of the physical location) where a SQL server 2008 R 2 cluster installation and MS Dynamics AX 4.0 is involved? Blog bot DAX Blogs 0 21.06.2014 19:19
Поймать SQL запрос при формировании отчета Qaz Qwerty DAX: Программирование 7 12.06.2008 01:46
SQL store procedure tangolp DAX: Администрирование 2 11.08.2006 22:24
Формирование отчета с динамически изменяемым числом столбцов. rumpleteazer DAX: Программирование 1 06.09.2002 11:25
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 19:03.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.