Как правильно выполнять запросы к базе данных из скриптов
В помощь разработчику... 08 Апр 2011Под катом кусок исходного кода.
1 | // Как правильно выполнять запросы к базе данных из скриптов: // using Atechnology.DBConnections2; // using Atechnology.Components; // public void Run(dbconn _db, DataRow [] _dr) ... // Если запрос предполагает получение одного значения или таблицы данных, то DataTable tblResult = new DataTable(); string txtResult = String.Empty; // Пишем сам текст запроса к БД, например db.command.CommandText = @" insert into orders (idorder) values (@idorder) "; // При использовании параметров в тексте запроса - инициализируем их значениями db.command.Parameters.Clear(); db.command.Parameters.AddWithValue( "@idorder", dbconn.GetGenId("gen_orders") ); // сгенерировать новый ключ idorder // Выполняем запрос db.OpenDB(); try { // В зависимости от типа запроса выбираем один вариант из нижеперечисленных: db.command.ExecuteNonQuery(); // выполнить запрос к БД (не выборка, т.е. insert|update) db.adapter.Fill(tblResult); // получить табличные данные из БД txtResult = Useful.GetString( db.command.ExecuteScalar(), "" ); // получить одно строковое значение } catch (Exception e) { throw new Exception(e.Message); } finally { db.CloseDB(); db.command.Parameters.Clear(); } |
Оценка сообщения: |
Метки: Atechnology, windraw
08 Фев 2013 в 13:22
Здравствуйте!
Никак не могу настроить отчеты с субрепортами. Есть 2 отчета, в обоих по 1 или 2 субрепортам. В каждом отчете 1 субрепорт некорректно отображатеся, то есть некоторые ячейки отчета, формируемые этим субрепортом, остаются пустыми.
Перерыл весь интернет, не нашел ничего, что могло бы хоть как-то приблизить меня к решению проблемы.
Пробовал сам сделать отчет с 0: вылазили всевозможные ошибки, при устранении которых появляются новые или WinDraw падает и приходится запускать заново.
Кто-нибудь уже сталкивался с подобной проблемой?
Буду рад любой помощи: ссылки, варианты решений и тп
Мои контакты:
icq 642231632
почта: cheremisin_k@mail.ru
12 Фев 2013 в 7:52
Сабрепорт представляет собой контрол, на котором можно отобразить другой независимый отчёт. Благодаря ему можно визуально поместить один отчёт в другой (внутри страницы в любом месте). Но в целом сабрепорт рекомендуется применять лишь когда 2 отчёта достаточно независимы друг от друга или между ними очень трудно установить связь. Во всех остальных случаях проще и правильнее использовать другие методы: связанные источники данных (датабэнды), группировки и контейнеры. Исходя из описания проблемы в комментарии, возникает предположение, что Вам нужно как раз второе — т.е. отобразить на странице отчёта связанные подчинённые данные для основных данных. Например, есть основной список позиций заказа, в котором перечислены все изделия (их рисунки, информация по ним и т.п.), и нам требуется под каждым таким изделием (рисунком) отобразить спецификацию по конкретно этому изделию (т.е. перечень материалов). Для этого между двумя источниками данных (sql-запросами) «изделия» и «спецификация» настраивается связь (в самом отчёте, relation). Под databand'ом изделий вставляется новый databand, завязанный на спецификацию. У этого второго databand'а проставляется ссылка на первый master databand и даётся ссылка на связь relation. И всё, теперь под каждым рисунком изделия будет корректно отображаться спецификация именно этого изделия. А чтобы более детально разобраться в проблеме, нам нужно взглянуть на сам отчёт и понять, что мы вообще хотим видеть благодаря этому отчёту (т.е. нужен доступ к mrt-файлу отчёта и его описанию), поскольку существует масса всевозможных решений, позволяющих обойти возникшие проблемы и решить их другим способом.
19 Фев 2013 в 12:29
Внедренец, спасибо за ответ.
Я все же хочу заморочиться с субрепортами)
Есть ряд отчетов с ними, которые работают, хочу изменить тот, который работает, но неправильно. Вот.
Одна из ошибок возникает с запросами с параметрами . То есть в запросе все норм, просто беру и копирую из другого рабочего запроса, не всегда даже изменяю. Один из параметров передается нажатием кнопки, формирование другого происходит на этапе построения запроса, описываются параметры в коде (в коде работающих отчетов), казалось бы все норм.
Делаю аналогичные запросы, такие же параметры, делаю кнопку, добавляю на нее событие (2 раза нажимаю, пишу туда условие, задающее параметр), но в коде они автоматически не генерятся и выдается ошибка «The error of compilation is found in the 'Report' report: Имя 'idorder' отсутствует в текущем контексте».
(в запросе параметр передается так: where mc.idorder = {idorder})
Код на c# (не знаю, бывают ли видроу с другими). Нужно инициализировать там эти параметры. Вписываю туда строки, но они не сохраняются. То есть пишу строку, перехожу во вкладку Page, потом обратно в код и внесенные изменения исчезают. Либо во вкладке код вношу изменения, все сохраняю, как обычно, выхожу из отчета, применяю изменения, снова захожу в редактирование этого отчета и опять в коде нет внесенных изменений!
Предыдущая программистка сказала, что так код не редактируется, это делается в каком-то отдельном окне. Окно по-честному искал, не нашел.
В связи с этим вопрос, как вручную можно редактировать код отчета?
(уж очень накипела эта тема с отчетами. Опыта работы мало, я всего на 2 курсе сейчас, получается делать все кроме отчета. То есть отчеты уже редактировал, но до этого все упиралось в подвинуть текстбенд, поменять свойства, 1 раз пришлось переделать запрос, все работало. Но отображение субрепортов хоть убей, не такое, каким должно быть)
Заранее спасибо!
19 Фев 2013 в 13:30
У меня еще 1 вопрос из той же темы.
Как можно добавить параметр в запрос, так чтобы он был инициализирован?
Для примера, параметр idorder в условии
where mc.idorder = {idorder} должен быть инициализирован номером заказа типа int. В рабочих запросах он присутствует в коде вот так:
public int idorder;
public override void SaveState (System.String stateName)
{
base.SaveState (stateName);
this.States.PushInt (stateName, this, «idorder», this.idorder);
this.States.Push (stateName, this, «PeopleFio», this.PeopleFio);
this.States.Push (stateName, this, «filt», this.filt);
}
public override void RestoreState (System.String stateName)
{
base.RestoreState (stateName);
this.idorder = this.States.PopInt (stateName, this, «idorder»);
this.PeopleFio = ((string)(this.States.Pop (stateName, this, «PeopleFio»)));
this.filt = ((string)(this.States.Pop (stateName, this, «filt»)));
}
private void InitializeComponent ()
{
this.Dictionary.Variables.Add (new Stimulsoft.Report.Dictionary.StiVariable («basic», «idorder», «idorder», "", typeof (int), «1257», false, Stimulsoft.Report.Dictionary.StiVariableInitBy.Value, false));
this.idorder = 1257;
this.header.Columns.AddRange (new Stimulsoft.Report.Dictionary.StiDataColumn[] {
new Stimulsoft.Report.Dictionary.StiDataColumn («idorder», «idorder», «idorder», typeof (int)), // другие кортежи таблицы...))
}
public class headerDataSource : Stimulsoft.Report.Dictionary.StiSqlSource
{
public virtual int idorder
{
get
{
return ((int)(StiReport.ChangeType (this["idorder"], typeof (int), true)));
}
}
}
В прошлом комментарии я написал, что код не получается редактировать.
Если есть способ обойтись без прямой редакции кода так, чтобы он все равно был сгенерирован для параметров запроса (к прим. {idorder}), ознакомьте меня с ним, пожалуйста.
19 Фев 2013 в 13:58
>> Как можно добавить параметр в запрос, так чтобы он был инициализирован?
>> Для примера, параметр idorder в условии
>> where mc.idorder = {idorder} должен быть инициализирован номером заказа типа int.
Для того чтобы добавить параметр в отчёт на стадии проектирования нужно во вкладке «Словарь» (если она скрыта — включите галочку в меню 'Вид' построителя отчётов) найти пункт «Переменные» (он находится чуть ниже пункта «Источники данных», в котором описываются сами sql-запросы). Щёлкните правой клавишей мыши по пункту «Переменные» и в открывшемся контекстном меню выберите подпункт «Новая переменная ...». Появится диалоговое окно, в котором и указываются: наименование переменной (например, idorder), её тип (строка, число и т.п.), значение по умолчанию (например, 12345, именно это значение подставится в sql-запрос в строке вида: " where mc.idorder = {idorder} "). Генератор отчётов сам сформирует необходимый код и на вкладке Code будет сгенерирована строка типа: «public int idorder;» Ничего дописывать, изменять, удалять на вкладке с кодом не нужно, всё делается вручную визуально через интерфейс самого построителя отчётов. Когда любой отчёт вызывается из программы winDraw, то в соответствующих переменных корректируется значение на текущее (например idorder станет равным ключу именно того заказа, для которого мы вызвали этот отчёт).
21 Фев 2013 в 12:56
Спасибо огромное!
Больше месяца голову ломал над старыми отчетами, а теперь еще и новый составить нужно, Вы мне очень помогли
26 Фев 2013 в 12:22
Здравствуйте!
Я опять с отчетами)
Есть отчет Тех карта, в тайтл бенде которого 1 из полей — количество изделий. Должно считать, как это ни странно, количство изделий во всем ПЗ))
С ним и проблема. Считает только количество изделий первого наименования.
Допустим, в ПЗ 5 окон (первый пункт) и 10 дверей (второй пункт). Отчет покажет количество изделий = 5, что, очевидно, неверно: должно быть 15.
Если в заказе всего 1 наименование, к примеру, 15 окон, то считает верно.
То есть в учет идет только 1 наименование.
Опять же, делал все, как в отчете, в котором это количество считается правильно:
запрос, вывод в отчет, GroupHeaderBand.
Про груп хидер бенд (GroupHeaderBand1).
Условие (Condition) в нем атрибут idmanufactdoc, отображающий внутренний уникальный номер ПЗ.
Выбирается в том же запросе, что и количество изделий.
Количество изделий считается по группе с одинаковым номером ПЗ idmanufactdoc:
Sum (GroupHeaderBand1,Title.mdp_qu)
Из таблицы Title mdp_qu — количество изделий
GroupHeaderBand1 — группирующий бэнд с атрибутом группировки idmanufactdoc
Где я мог накосячить? Что можно исправить?
Заранее спасибо!
26 Фев 2013 в 12:25
К предыдущему посту:
отчет считает количество изделий первого наименования, а должен количество изделий во всем ПЗ, то есть по всем наименованиям.
26 Фев 2013 в 12:34
К предыдущему еще 1 дополнение:
пробовал группировать (Писать в Group header band) по другому атрибуту: по внутреннему номер (id) заказа. Это неправильно с точки зрения бизнес логики, но не видел, чтобы ПЗ формировались на основе нескольких заказов, да и попробовать стоило. Результат тот же: считает только количество изделий по первому наименованию(
26 Фев 2013 в 13:01
Результат такой же, как и без использования групп хидер бэнд, если честно
26 Фев 2013 в 13:30
К тому же посту:
сделал отчет, в котором тестирую как да что с количеством изделий.
В нем:
-ReportTitleBand
-GroupHeadrBand (Condition = Title.idmanufactdoc)
-DataBand
Заголовок пустой.
В датабенде текстовое поле: Number of positions: {Sum (GroupHeaderBand1,Title.mdp_qu)}
То есть, поле должно показывать то самое количество изделий в ПЗ.
Наблюдаю интересную вещь:
1)Если в датабенде указать источник таблицу Title, то в отчете показыват количество изделий правильно, но в 4 строки (откуда??), то есть вижу в отчете:
Number of positions: 15
Number of positions: 15
Number of positions: 15
Number of positions: 15
2) Если в датабенде убрать источник (Not Assigned), то отчет показывает неправильное количество изделий (1), но в 1 строку:
Number of positions: 1
По секрету, это количество изделий последнего наименования.
3) Если вместо источника данных в дата бенде указать Count Data, к примеру 1, то результат такой же, как во 2 пункте.
Лажа. Не имею ни малейшего представления почему так. Хочется, чтобы было правильно количество изделий, как в пункте 1, но в 1 строку, как в пункте 2.
Почему так происходит? Как исправить?
26 Фев 2013 в 14:04
ПРОБЛЕМА РЕШЕНА
Теперь требуется понять, почему она решилась)
Что я сделал:
в отчет добавил пустой датабенд с источком Title, таблицей из которой все берется. Расположил его над ДатаБенд1
ДатаБенд1 оставил без источника.
Теперь структура такова:
-ReportTitleBand1
-GroupHeaderBand1
-DataBand2 (Data Source = Title)
-DataBand1 (Not Assigned)
-Table1
Почему сработало? Перевожусь на гумфак после таких метаморфоз)
28 Фев 2013 в 15:05
Если у Вас в отчёте имеется GroupHeaderBand, а под ним DataBand — то итоговое поле с суммой {Sum (GroupHeaderBand1,Title.mdp_qu)} нужно размещать НЕ на DataBand, а на дополнительном GroupFooterBand, размещённом под ним! Т.е. под DataBand'ом добавьте GroupFooterBand, и уже на нём отображайте текстовые поля с итогами.
04 Мар 2013 в 13:56
Спасибо!