OberonCore https://forum.oberoncore.ru/ |
|
Чтение из таблиц MS SQL7 https://forum.oberoncore.ru/viewtopic.php?f=35&t=1030 |
Страница 1 из 2 |
Автор: | stern [ Вторник, 17 Июнь, 2008 12:42 ] |
Заголовок сообщения: | Чтение из таблиц MS SQL7 |
Здравствуйте. Пытаюсь считать из таблицы 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; Что делаю не так? И как считать значение из какой-то произвольной ячейки? Спасибо. Отображение исходного кода поправлено администратором. |
Автор: | Иван Кузьмицкий [ Вторник, 17 Июнь, 2008 13:16 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
Нужно поля в записи делать экспортированными: Код: TYPE
Str1* = RECORD id*: INTEGER; name*: ARRAY 32 OF CHAR; ceo*: ARRAY 32 OF CHAR; employees*: INTEGER END; |
Автор: | stern [ Вторник, 17 Июнь, 2008 14:14 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
Спасибо! Для тех, кто мало знает (навроде меня ) уточню на всякий случай, что экспортирован должен быть именно тип со всеми полями, а соответствующая переменная может быть объявлена и локально. Во всяком случае, у меня так работает. Теперь еще вопросы. Можно ли создать таблицу определенной структуры не расписывая все поля записи руками? Как-нибудь так: CREATE TABLE Table1 (:Sample.company) где Sample.company есть экспортированный интерактор. То, что можно записать таким образом INSERT INTO Companies VALUES (:Sample.company) написано в руководстве. |
Автор: | Иван Кузьмицкий [ Вторник, 17 Июнь, 2008 14:48 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
stern писал(а): Можно ли создать таблицу определенной структуры не расписывая все поля записи руками? Как-нибудь так: CREATE TABLE Table1 (:Sample.company) где Sample.company есть экспортированный интерактор. Ни разу не пробовал. |
Автор: | Евгений Темиргалеев [ Вторник, 17 Июнь, 2008 15:17 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
В документации сказано, что вместо записи-интерактора подставляются значения полей. Так что готовыми средствами нельзя. Да и откуда подсистема 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) |
Автор: | Илья Ермаков [ Вторник, 17 Июнь, 2008 18:22 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
Посмотрите на нашем сайте библиотеку Mt, модуль MtSql. Я там два года назад что-то делал для облегчения-автоматизации... Хоть убей не помню уже что... |
Автор: | Иван Кузьмицкий [ Вторник, 17 Июнь, 2008 20:26 ] | ||
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 | ||
Мы у себя используем библиотечку Stern. В ней есть модуль Sql, немного облегчающий работу с SqlDB. Это абстрактный интерфейс, а реализация сделана для MySQL (два варианта - SternMysql, для сервера с поддержкой транзакций, и SternMysql3, для старой версии сервера). Думаю, для MSSQL не будет радикальных отличий.
|
Автор: | stern [ Вторник, 17 Июнь, 2008 20:33 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
Всем спасибо! Библиотеку и пр. обязательно посмотрю. Код, предложенный Евгением, работает. Я его лишь немножко доработал таким образом: Код: 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; Есть некоторые "непонятки" с типами (там, где отмечено (*???*)), но в данный момент для меня это не важно. |
Автор: | Евгений Темиргалеев [ Вторник, 17 Июнь, 2008 21:37 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
Во-первых, лучше писать имена констант вместо их значений: Код: 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 |
Автор: | stern [ Понедельник, 23 Июнь, 2008 14:38 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
Знаю, что в таблице имеется поле с именем 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*) ............... Не получается. Что делаю не так? |
Автор: | Иван Кузьмицкий [ Понедельник, 23 Июнь, 2008 15:02 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
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, и получите результат. |
Автор: | stern [ Понедельник, 23 Июнь, 2008 17:33 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
Спасибо, работает. Выглядит примерно так (только ногами по голове за код не бить:)): Код: 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; |
Автор: | Евгений Темиргалеев [ Понедельник, 23 Июнь, 2008 18:22 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
Некоторые моменты по оформлению: - разыменование обычно опускают: names.fields[i] = name; НЕ ВЕРНО - при записи последовательности операторов (StatementSequence) не принято ставить в конце пустой оператор. Например, вместо IF a THEN b; c; <пустой оператор> END пишут IF a THEN b; c END |
Автор: | stern [ Понедельник, 23 Июнь, 2008 21:28 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
По поводу пустого оператора поправка принимается, а вот по поводу разыменования... Без него у меня не "работает". |
Автор: | Евгений Темиргалеев [ Понедельник, 23 Июнь, 2008 22:06 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
Эхех... думать надо как следует перед тем как давать советы. Или не давать советов. Прошу прощения. 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 |
Автор: | Алексей_В [ Пятница, 02 Январь, 2009 02:29 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
День добрый! Попробовал пример в начале этой темы для пподсоединения к Firebird. Все работает, единственно сразу после создания таблицы пришлось еще Commit вставить, а то Firebird создание таблицы фиксировать не хотел... Но подскажите, пожалуста, я запускаю приложение как Open As Aux Dialog (до сих пор не знаю, правильно ли это). Когда добавляю в проект форму и указываю линк на имя модуля, понятно, получаю окно с двумя кнопками, которые и вызывают наши процедуры. Но я хочу добавить на форму StdTables - что надо добавить в код модуля, чтобы содержимое таблицы базы данных выводилось в ББ в этот грид, а не только в лог? Кажется table из table := db.NewTable() надо привязать к гриду, но как? Тем более, это table наверно надо тоже сделать экспортируемым? И еще, подскажите, пожалуста, у меня ощущение, что стандартный грид слабоват. Существует ли что-то для написание простых без по типу как на основе TDBGrid в Delphi или Lazarus? |
Автор: | Иван Кузьмицкий [ Пятница, 02 Январь, 2009 10:54 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
Вот тут пример работы с StdTables: viewtopic.php?f=5&t=1285&p=22652#p22652 |
Автор: | Алексей_В [ Вторник, 06 Январь, 2009 14:50 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
День добрый! Прошел по ссыслке, спасибо, все заработало. С FireBird проблем пока нет. Вот только не пойму, как все-таки правильно отображать формы на экране. Я делаю пока вот так - "AleksSql.Do; StdCmds.OpenAuxDialog('Aleks\Rsrc\SqlGrid.odc', 'Список')" Во первых, хотелось бы, чтобы у формы можно было менять размер. Кроме того, когда я положил на форму визуальный TAB - то оказалось, что после открытия формы указанной командой на TAB осталась сетка, как в режиме редактирования, а грид ведет себя так, как будто я вообще работаю в режиме разработки графического интерфейса. Предположим, что проблему изменения размера своих форм можно решить, если положить контролы например в пустой документ, но как там поставить цвет фона, что было похоже на стандартное окно... да и шаг выставления контролов там не удобный, все таки это больше текстовый редактор. Есть ли где-то информация по созданию интерфейса пользователя в ББ ? А то в хелпе я пока нашел только работу с интеракторами, это в первом приближении понял, а как формы-то отображать и работать с ними? |
Автор: | Valery Solovey [ Вторник, 06 Январь, 2009 15:43 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
Алексей_В писал(а): Я делаю пока вот так - "AleksSql.Do; StdCmds.OpenAuxDialog('Aleks\Rsrc\SqlGrid.odc', 'Список')" Во первых, хотелось бы, чтобы у формы можно было менять размер. Попробуйте вместо OpenAuxDialog использовать OpenAux или OpenBrowser. Различия описаны в документации. Также, неплохо будет прочесть документацию и по остальным оупенам (может понадобится). Алексей_В писал(а): Кроме того, когда я положил на форму визуальный TAB - то оказалось, что после открытия формы указанной командой на TAB осталась сетка, как в режиме редактирования, а грид ведет себя так, как будто я вообще работаю в режиме разработки графического интерфейса. При редактировании формы выделите каждое из этих отображений и переведите их из режима редактирования в более подходящий. Если ни одно отображение не выбрано, то перевод режимов будет сказываться на форме. Рекурсии нет, каждому отображению нужно задавать режим отдельно.Алексей_В писал(а): Есть ли где-то информация по созданию интерфейса пользователя в ББ ? А то в хелпе я пока нашел только работу с интеракторами, это в первом приближении понял, а как формы-то отображать и работать с ними? У Раскина точно есть : ).
|
Автор: | Пётр Кушнир [ Вторник, 06 Январь, 2009 15:55 ] |
Заголовок сообщения: | Re: Чтение из таблиц MS SQL7 |
Алексей_В писал(а): StdCmds.OpenAuxDialog('Aleks\Rsrc\SqlGrid.odc', 'Список') Это правильный способ отображения формы. Есть ещё StdCmds.OpenToolDialog - открывает указанную форму поверх всех окон. Если вы про модальность, то её нет, такое вот интерфейсное решение.Алексей_В писал(а): хотелось бы, чтобы у формы можно было менять размер. Этого тоже нет в стандартном интерфейсе. Решений несколько, их описание заслуживает отдельного поста, чтобы не оффтопить - в личке.Алексей_В писал(а): Кроме того, когда я положил на форму визуальный TAB - то оказалось, что после открытия формы указанной командой на TAB осталась сетка, как в режиме редактирования, а грид ведет себя так, как будто я вообще работаю в режиме разработки графического интерфейса. В свойствах контрола TabView надо выделить пункт "All tabs in Mask mode" для переключения в режим маски, который используется при работе с формой.Алексей_В писал(а): Предположим, что проблему изменения размера своих форм можно решить, если положить контролы например в пустой документ, но как там поставить цвет фона, что было похоже на стандартное окно... Это ошибочный путь.
|
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |