OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Среда, 24 Апрель, 2019 07:27

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 27 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Чтение из таблиц MS SQL7
СообщениеДобавлено: Вторник, 17 Июнь, 2008 12:42 

Зарегистрирован: Вторник, 17 Июнь, 2008 12:13
Сообщения: 28
Здравствуйте. Пытаюсь считать из таблицы MS SQL7 данные. Не получается. Хотя таблицы создаются, можно посмотреть их содержимое. В этом плане все нормально. Но считать не получается.
Делаю так:
Код:
   IMPORT Kernel, SqlDB, StdLog;
   
   CONST
      protocol = "SqlOdbc3";
      id = ""; password = "";
      datasource = "MS_SQL7_TEST_Client";

      TYPE Str1 = RECORD
               id: INTEGER;
               name: ARRAY 32 OF CHAR;
               ceo: ARRAY 32 OF CHAR;
               employees: INTEGER
            END;   
   VAR
      str1*: Str1;

   PROCEDURE Create*;
      VAR db: SqlDB.Database; res: INTEGER;

   BEGIN
      SqlDB.OpenDatabase(protocol, id, password, datasource, SqlDB.async, SqlDB.hideErrors, db, res);
      IF db # NIL THEN
         db.Exec("CREATE TABLE Table1 (id INTEGER, name VARCHAR(32), ceo VARCHAR(32), employees INTEGER)");
         db.Exec("INSERT INTO Table1 VALUES (11, 'Test1', 'qwer', 234)");
         db.Exec("INSERT INTO Table1 VALUES (12, 'Test2', 'qewr-rty', 1234)");

         db.Commit
      END;
      db := NIL;
      Kernel.Cleanup   
   END Create;

   PROCEDURE ReadStr*;
      VAR
         db: SqlDB.Database;
         res: INTEGER;
         table: SqlDB.Table;
         str1: Str1;
         
   BEGIN
      SqlDB.OpenDatabase(protocol, id, password, datasource, SqlDB.async, SqlDB.hideErrors, db, res);
      IF db # NIL THEN
         table := db.NewTable();
         
         table.Exec("SELECT * FROM Table1 WHERE id > 0");
         table.Read(1, str1); ;

         StdLog.Int(str1.id); StdLog.Ln;
         StdLog.String(str1.name); StdLog.Ln;
         StdLog.String(str1.ceo); StdLog.Ln;
         StdLog.Int(str1.employees); StdLog.Ln;

         db.Commit
      END;
      table := NIL;
      db := NIL;
      Kernel.Cleanup;   (* garbage collector closes database *)
   END ReadStr;


Что делаю не так? И как считать значение из какой-то произвольной ячейки? Спасибо.

Отображение исходного кода поправлено администратором.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Вторник, 17 Июнь, 2008 13:16 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2931
Откуда: г. Ярославль
Нужно поля в записи делать экспортированными:
Код:
TYPE
Str1* = RECORD
   id*: INTEGER;
   name*: ARRAY 32 OF CHAR;
   ceo*: ARRAY 32 OF CHAR;
   employees*: INTEGER
END;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Вторник, 17 Июнь, 2008 14:14 

Зарегистрирован: Вторник, 17 Июнь, 2008 12:13
Сообщения: 28
Спасибо! Для тех, кто мало знает (навроде меня :)) уточню на всякий случай, что экспортирован должен быть именно тип со всеми полями, а соответствующая переменная может быть объявлена и локально. Во всяком случае, у меня так работает.
Теперь еще вопросы.
Можно ли создать таблицу определенной структуры не расписывая все поля записи руками? Как-нибудь так:
CREATE TABLE Table1 (:Sample.company)
где Sample.company есть экспортированный интерактор.

То, что можно записать таким образом
INSERT INTO Companies VALUES (:Sample.company)
написано в руководстве.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Вторник, 17 Июнь, 2008 14:48 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2931
Откуда: г. Ярославль
stern писал(а):
Можно ли создать таблицу определенной структуры не расписывая все поля записи руками? Как-нибудь так:
CREATE TABLE Table1 (:Sample.company)
где Sample.company есть экспортированный интерактор.

Ни разу не пробовал.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Вторник, 17 Июнь, 2008 15:17 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4489
Откуда: Россия, Орёл
В документации сказано, что вместо записи-интерактора подставляются значения полей. Так что готовыми средствами нельзя. Да и откуда подсистема Sql узнает какой диалект Вы используете и как отображать типы КП на типы этого диалекта SQL?

Однако, если Вы почитаете документацию по модулю Meta, сможете сами сделать процедуру для построения запроса и создания таблицы под определённый тип записей/интерактор. Что-то вроде:
Код:
PROCEDURE GenQuery (IN table, type: ARRAY OF CHAR; OUT query: ARRAY OF CHAR);
  VAR r: Meta.Item; s: Meta.Scanner; n: Meta.Name;
BEGIN
  Meta.LookupPath(type, r); ASSERT(r.typ = Meta.recTyp, 20);
  s.ConnectTo(r);
  query := "CREATE TABLE " + table + "(";
  s.Scan;
  WHILE ~s.eos DO
    s.GetObjName(n);
    CASE s.this.typ OF
    ...
    END;
    s.Scan
  END;
  query := query + ")"
END GenQuery;

...
GenQuery("Table1", "Sample.MyRecord", query); db.Exec(query)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Вторник, 17 Июнь, 2008 18:22 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9115
Откуда: Россия, Орёл
Посмотрите на нашем сайте библиотеку Mt, модуль MtSql.
Я там два года назад что-то делал для облегчения-автоматизации...
Хоть убей не помню уже что... :-)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Вторник, 17 Июнь, 2008 20:26 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2931
Откуда: г. Ярославль
Мы у себя используем библиотечку Stern. В ней есть модуль Sql, немного облегчающий работу с SqlDB.

Это абстрактный интерфейс, а реализация сделана для MySQL (два варианта - SternMysql, для сервера с поддержкой транзакций, и SternMysql3, для старой версии сервера). Думаю, для MSSQL не будет радикальных отличий.


Вложения:
Stern.7z [53.9 КБ]
Скачиваний: 374
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Вторник, 17 Июнь, 2008 20:33 

Зарегистрирован: Вторник, 17 Июнь, 2008 12:13
Сообщения: 28
Всем спасибо! Библиотеку и пр. обязательно посмотрю. Код, предложенный Евгением, работает. Я его лишь немножко доработал таким образом:

Код:
   PROCEDURE GenQuery (IN table, type: ARRAY OF CHAR; OUT query: ARRAY OF CHAR);
       VAR r: Meta.Item; s: Meta.Scanner; n: Meta.Name; arrLen, nameType: ARRAY 20 OF CHAR;
   BEGIN
      Meta.LookupPath(type, r); ASSERT(r.typ = Meta.recTyp, 20);
      s.ConnectTo(r);
      query := "CREATE TABLE " + table + " (";
      s.Scan;
      WHILE ~s.eos DO
         s.GetObjName(n);
         CASE s.this.typ OF
            1: nameType := "INTEGER";   (*???*)
            |2: nameType :=  "VARCHAR(1)";   (*???*)
            |3: nameType :=  "VARCHAR(1)";   (*???*)
            |4: nameType :=   "INTEGER";    (*???*)
            |5: nameType :=  "INTEGER";   (*???*)
            |6: nameType :=  "INTEGER";
            |7: nameType :=  "REAL";   (*???*)
            |8: nameType :=  "REAL";
            |10: nameType := "INTEGER";   (*???*)
            |18:
               Strings.IntToString(s.this.Len(), arrLen);
               nameType := "VARCHAR(" + arrLen + ") "; 
         END;

         s.Scan;
         query := query + n + " " + nameType;
         IF ~s.eos THEN query := query + ", " END
      END;
      query := query + ")";
      StdLog.String(query); StdLog.Ln
   END GenQuery;


Есть некоторые "непонятки" с типами (там, где отмечено (*???*)), но в данный момент для меня это не важно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Вторник, 17 Июнь, 2008 21:37 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4489
Откуда: Россия, Орёл
Во-первых, лучше писать имена констант вместо их значений:
Код:
Meta.boolTyp: nameType := "INTEGER";   (*???*)

Во-вторых, нужно смотреть Dev-Man, какие типы поддерживаются и, фактически, только они могут быть типами полей записи. (Полный вариант - разрешены поля-записи (с полями разрешенных типов).) Как будут называться типы в SQL-запросе, зависит "от конкретной базы данных и драйвера Sql". Т. е. генерация запроса возможна под конкретную базу и драйвер Sql, одной процедуры на все случаи жизни не получится.
Dev-Man писал(а):
Следующие типы Компонентного Паскаля интерпертируются SqlDB:
BOOLEAN
BYTE, SHORTINT, INTEGER
SHORTREAL, REAL
ARRAY OF CHAR
Dates.Date
Dates.Time
Dialog.Currency
Dialog.List
Dialog.Combo
SqlDB.Blob

Каким образом эти типы будут спроецированы на типы данных SQL, зависит от конкретной базы данных и драйвера Sql. Следующая таблица является примером, соответствующим Microsoft Sql Server с доступом через ODBC:

SQL | Компонентный Паскаль
{bit, tinyint, smallint, integer, bigint} | {BOOLEAN(1), BYTE, SHORTINT, INTEGER, Dialog.List}
{real, float(p), double precision} | {SHORTREAL, REAL}
{char(n)(2), varchar(n)(3), long varchar} | {ARRAY OF CHAR, Dialog.Combo}
{decimal(p, s), numeric(p, s)} | Dialog.Currency
{date, timestamp(4)} | Dates.Date
{time, timestamp(4)} | Dates.Time
{binary(n), varbinary(n), long varbinay) | SqlDB.Blob


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Понедельник, 23 Июнь, 2008 14:38 

Зарегистрирован: Вторник, 17 Июнь, 2008 12:13
Сообщения: 28
Знаю, что в таблице имеется поле с именем name и типом ARRAY 32 OF CHAR. Больше о структуре таблицы ничего не известно (так получилось :)). Как прочитать значение поля name в нужной строке? Делаю так:

Код:
......
      TYPE Str3* = RECORD
               name*: ARRAY 32 OF CHAR;
            END;   

......
         table.Exec("SELECT name FROM Table1");
         table.Read(1, str3); (*пытаюсь считать из первой строки значение поля name*)
...............


Не получается. Что делаю не так?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Понедельник, 23 Июнь, 2008 15:02 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2931
Откуда: г. Ярославль
PROCEDURE (t: Table) Read (row: INTEGER; VAR data: ANYREC)

Цитата:
Считывает сроку row результирующей таблицы в интерактор data. Общий тип данных Row, который состоит из открытого массива строк, может использоваться для чтения строки данных из произвольной таблицы. Все значения из таблицы в этом случае преобразуются в строковое представление.


Сделайте

names, row: SqlDB.Row;
...
table.Read(SqlDB.names, names);
table.Read(1, row);

Потом нужно определить номер поля в row по имени поля в names, и получите результат.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Понедельник, 23 Июнь, 2008 17:33 

Зарегистрирован: Вторник, 17 Июнь, 2008 12:13
Сообщения: 28
Спасибо, работает. Выглядит примерно так (только ногами по голове за код не бить:)):

Код:
         table.Exec("SELECT * FROM Table1");
         table.Read(SqlDB.names, names); (*считываем заголовок таблицы*)

         len := LEN(names.fields); pos := -1; i := 0;
         WHILE len > i DO
            IF (names.fields[i]^ = name) THEN pos := i END;
            INC(i);
         END;

         IF pos # -1 THEN
            table.Read(1, row); (*а теперь считываем первую строку таблицы*)
            StdLog.String(row.fields[pos]);
         END;   


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Понедельник, 23 Июнь, 2008 18:22 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4489
Откуда: Россия, Орёл
Некоторые моменты по оформлению:
- разыменование обычно опускают: names.fields[i] = name; НЕ ВЕРНО
- при записи последовательности операторов (StatementSequence) не принято ставить в конце пустой оператор. Например, вместо IF a THEN b; c; <пустой оператор> END пишут IF a THEN b; c END


Последний раз редактировалось Евгений Темиргалеев Понедельник, 23 Июнь, 2008 22:18, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Понедельник, 23 Июнь, 2008 21:28 

Зарегистрирован: Вторник, 17 Июнь, 2008 12:13
Сообщения: 28
По поводу пустого оператора поправка принимается, а вот по поводу разыменования... Без него у меня не "работает". :?:


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Понедельник, 23 Июнь, 2008 22:06 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4489
Откуда: Россия, Орёл
Эхех... думать надо как следует перед тем как давать советы. Или не давать советов. Прошу прощения.

names.fields[i]: POINTER TO ARRAY OF CHAR
name: ARRAY ? OF CHAR

При сравнении ARRAY OF CHAR, выборка строки $ применяется не явно:
names.fields[i]^ = name вместо names.fields[i]^$ =name$

Выборка строки подразумевает разыменовывание: names.fields[i]$ вместо names.fields[i]^$.

Но не то и другое сразу... Подробнее см. Сообщение о языке, 8.1


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Пятница, 02 Январь, 2009 02:29 

Зарегистрирован: Четверг, 04 Декабрь, 2008 20:41
Сообщения: 16
День добрый!
Попробовал пример в начале этой темы для пподсоединения к Firebird. Все работает, единственно сразу после создания таблицы пришлось еще Commit вставить, а то Firebird создание таблицы фиксировать не хотел... Но подскажите, пожалуста, я запускаю приложение как Open As Aux Dialog (до сих пор не знаю, правильно ли это). Когда добавляю в проект форму и указываю линк на имя модуля, понятно, получаю окно с двумя кнопками, которые и вызывают наши процедуры. Но я хочу добавить на форму StdTables - что надо добавить в код модуля, чтобы содержимое таблицы базы данных выводилось в ББ в этот грид, а не только в лог? Кажется table из table := db.NewTable()
надо привязать к гриду, но как? Тем более, это table наверно надо тоже сделать экспортируемым? И еще, подскажите, пожалуста, у меня ощущение, что стандартный грид слабоват. Существует ли что-то для написание простых без по типу как на основе TDBGrid в Delphi или Lazarus?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Пятница, 02 Январь, 2009 10:54 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2931
Откуда: г. Ярославль
Вот тут пример работы с StdTables:
viewtopic.php?f=5&t=1285&p=22652#p22652


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Вторник, 06 Январь, 2009 14:50 

Зарегистрирован: Четверг, 04 Декабрь, 2008 20:41
Сообщения: 16
День добрый!

Прошел по ссыслке, спасибо, все заработало. С FireBird проблем пока нет. Вот только не пойму, как все-таки правильно отображать формы на экране. Я делаю пока вот так - "AleksSql.Do; StdCmds.OpenAuxDialog('Aleks\Rsrc\SqlGrid.odc', 'Список')" Во первых, хотелось бы, чтобы у формы можно было менять размер. Кроме того, когда я положил на форму визуальный TAB - то оказалось, что после открытия формы указанной командой на TAB осталась сетка, как в режиме редактирования, а грид ведет себя так, как будто я вообще работаю в режиме разработки графического интерфейса. Предположим, что проблему изменения размера своих форм можно решить, если положить контролы например в пустой документ, но как там поставить цвет фона, что было похоже на стандартное окно... да и шаг выставления контролов там не удобный, все таки это больше текстовый редактор.
Есть ли где-то информация по созданию интерфейса пользователя в ББ ? А то в хелпе я пока нашел только работу с интеракторами, это в первом приближении понял, а как формы-то отображать и работать с ними?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Вторник, 06 Январь, 2009 15:43 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1537
Откуда: Беларусь, Минск
Алексей_В писал(а):
Я делаю пока вот так - "AleksSql.Do; StdCmds.OpenAuxDialog('Aleks\Rsrc\SqlGrid.odc', 'Список')" Во первых, хотелось бы, чтобы у формы можно было менять размер.
Попробуйте вместо OpenAuxDialog использовать OpenAux или OpenBrowser. Различия описаны в документации. Также, неплохо будет прочесть документацию и по остальным оупенам (может понадобится).
Алексей_В писал(а):
Кроме того, когда я положил на форму визуальный TAB - то оказалось, что после открытия формы указанной командой на TAB осталась сетка, как в режиме редактирования, а грид ведет себя так, как будто я вообще работаю в режиме разработки графического интерфейса.
При редактировании формы выделите каждое из этих отображений и переведите их из режима редактирования в более подходящий. Если ни одно отображение не выбрано, то перевод режимов будет сказываться на форме. Рекурсии нет, каждому отображению нужно задавать режим отдельно.
Алексей_В писал(а):
Есть ли где-то информация по созданию интерфейса пользователя в ББ ? А то в хелпе я пока нашел только работу с интеракторами, это в первом приближении понял, а как формы-то отображать и работать с ними?
У Раскина точно есть : ).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Чтение из таблиц MS SQL7
СообщениеДобавлено: Вторник, 06 Январь, 2009 15:55 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2567
Откуда: Россия, Ярославль
Алексей_В писал(а):
StdCmds.OpenAuxDialog('Aleks\Rsrc\SqlGrid.odc', 'Список')
Это правильный способ отображения формы. Есть ещё StdCmds.OpenToolDialog - открывает указанную форму поверх всех окон. Если вы про модальность, то её нет, такое вот интерфейсное решение.
Алексей_В писал(а):
хотелось бы, чтобы у формы можно было менять размер.
Этого тоже нет в стандартном интерфейсе. Решений несколько, их описание заслуживает отдельного поста, чтобы не оффтопить - в личке.
Алексей_В писал(а):
Кроме того, когда я положил на форму визуальный TAB - то оказалось, что после открытия формы указанной командой на TAB осталась сетка, как в режиме редактирования, а грид ведет себя так, как будто я вообще работаю в режиме разработки графического интерфейса.
В свойствах контрола TabView надо выделить пункт "All tabs in Mask mode" для переключения в режим маски, который используется при работе с формой.
Алексей_В писал(а):
Предположим, что проблему изменения размера своих форм можно решить, если положить контролы например в пустой документ, но как там поставить цвет фона, что было похоже на стандартное окно...
Это ошибочный путь.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 27 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


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

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2019, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB