|
|
|
Embedded SQL via ODBC
|
|||
|---|---|---|---|
|
#18+
Уважаемые! Давайте поговорим о ESQL и ODBC. Кто что юзает? в чем преимущества и в чем недостатки этих подходов? У кого есть опыт работы в Embedded SQL? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2003, 12:56 |
|
||
|
Embedded SQL via ODBC
|
|||
|---|---|---|---|
|
#18+
но что здесь может быть интересно? ESQL это для дибиту. я много чего написал using embedded sql для DB2 Workstaton/ OS/400 / OS/390. не уверен, стоит ли его использовать с другими базами. я пробовал ESQL с Microsoft SQL Server, так ESQL там очень убогой и через задницу. bnd-шник представляет собой хранимую процедуру на SQL, а в программе на host language просто подставляются вызовы SP. в качестве host language мохно использовать исключительно С. ESQL различается для баз. даже при портировании программы между различными дибиту, приходится вносить исправления. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2003, 15:23 |
|
||
|
Embedded SQL via ODBC
|
|||
|---|---|---|---|
|
#18+
при использовании ESQL - не надо настраивать odbc драйвер. теоретически система получается проще и быстрее. использовал ESQL в C для доступа к Sybase ASA (6.x, 7.x, 8.x), Oracle 8.x. что бы не писать select, insert, update для каждой таблице использую sqlda - область. переносимость ессно будет ни к черту. пробовал работать с FB. даже sqlda- области в ASA и FB отличаются сильно. а толком использовть ESQL от FB так и не удалось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2003, 02:17 |
|
||
|
Embedded SQL via ODBC
|
|||
|---|---|---|---|
|
#18+
Меня еще интересует вот такой вопрос: Как в других базах данных и насколько хорошо поддерживается Embedded SQL/C++ Например, можно ли хост перевнные инициализировать по ссылке, через указатель, делать их членами класса. Я знаю что всё это отлично поддерживается в DB2. В Sybase к сожалению такие возможности отсутствуют. А как обстоят дела по этому вопросу у Oracle? вроде эта фишка называется PRO*C. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2003, 16:09 |
|
||
|
Embedded SQL via ODBC
|
|||
|---|---|---|---|
|
#18+
в оракле действительно называется PRO*C -- хост перевнные инициализировать по ссылке, через указатель, делать их членами класса В Sybase к сожалению такие возможности отсутствуют. ------------ ой, млин, а я не знал, что у Sybase такие траблы. поэтому, переменные для обмена с бд у меня живут как члены класса Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. таблица вот такая Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. структура ASAI_TSde представляет собой список который в кишках программы связывается с область SQLDA - она и играет роль хост переменных Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. пример создания инсерта Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2003, 23:10 |
|
||
|
Embedded SQL via ODBC
|
|||
|---|---|---|---|
|
#18+
ИМХО ESQL-программы получаются проще и понятнее чем их ODBC аналоги. Правда в ODBC программирование я сильно не зарывался. Универсальность ODBC - фикция, так что смело начинай работать с ESQL, при переходе на другой SQL сервер все равно придется подправлять руками что ODBC что ESQL. К тому же ODBC драйвера далеко не безгрешны, так что имеем дополнительный источник ошибок. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.10.2003, 05:15 |
|
||
|
Embedded SQL via ODBC
|
|||
|---|---|---|---|
|
#18+
2 tchingiz )) Все примерно правильно, но я говорил немножко о другом: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. Причем определение класса CMyRec можно вставлять в заголовочный файл а затем инклудить его: EXEC SQL INCLUDE 'CMyRec.h'; Вот это я и называю настоящей поддержкой C++ А можно вообще fetch вызывать в конструкторе, тогда имеем такую фишку: EXEC SQL OPEN CMyRec; CMyRec* mv=new CMyRec[1000]; EXEC SQL CLOSE CMyRec; В результате выполнения такой конструкции получаем сразу массив уже заполненных структур; Единственный вопрос: Размер массива должен соответвовать количеству выбираемых записей, в противном случае нужно подумать об обработке исключений; Сравни теперь свой код, по длине и по ясности с моим, не говоря уж об ODBC. И еще такая вещь - всё что я написал - это статический SQL, который естественно выполняется быстрее динамического. И былее эффективен при частых вызовах, более безопасен, и не требует больших накладных расходов при администрировании. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.10.2003, 10:37 |
|
||
|
Embedded SQL via ODBC
|
|||
|---|---|---|---|
|
#18+
2gardeman гы ну ясное дело что статический быстрее и понятнее. со статического я начал тоже. только это уже другая тема попишешь для каждой новой таблицы новый код может о другой теме задумаешься (и перейдешь на sqlda). все что я привел - я уже не пишу. ;) а либо написал давно (два года назад), либо генерирую программой sql2C++ под любую таблицу, обзор (до сохраненок руки не дошли). поэтому код достаточно сложный (кстати с поддержкой индикатора для хранения NULL и возврата ошибок в поле, чего нет у тебя ) а собственно оператор insert выглядит так Код: plaintext 1. 2. 3. 4. 5. 6. в поле для уида записи структуры для работы с таблицей Cmd4Pmp из заданной базы данных ложится новый уникальный идентификотор из строки с и строчка вставляется в таблицы. в p возвращается id записи. более того я сознательно избегаю создавать сложные обьекты и дополнительные буфера для записей, а работаю с одной строчкой в буфере sql-сервера. /* кстати о ESQL в FB/Iterbase - оказалось, что там нет перемещения назад и произвольного позиционирования в буферу SQL сервера. в Oracle и ASA есть. поэтому в FB без собственного промежуточного буфера (и проблем синхронизации собственно буфера и буфера SQL сервера) не обойтись. :((( */ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2003, 00:25 |
|
||
|
Embedded SQL via ODBC
|
|||
|---|---|---|---|
|
#18+
Говоришь генерируешь?) это хорошо! Это правильно...)) Я тоже генерирую А на счет NULL величин - эт вы меня зря так обижаете. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. вот таким образом и будет тебе индикаторная переменная. А вот на счет генерации, у db2 есть классная утилитка db2dclgn, которая генерит структуру любой таблицы в любом формате - С,COBOL,FORTRAN... в результате работы получается заголовочный файл, ну например: Код: plaintext 1. 2. 3. 4. запускаем db2dclgn -d {database} -t test -i в результате имеем заголовочный файл Код: plaintext 1. 2. 3. 4. 5. 6. test_ind - Это будет массив индексных переменных а дальше прописываем примерно такую структуру: Код: plaintext 1. 2. 3. 4. 5. 6. 7. и, пользуясь тем что db2 может грузить зяпись прямо в структуру имеем возможность написать так в методе fetch(): Код: plaintext 1. 2. 3. Заметь - запись находится сразу в структуре, которая является членом класса. Имеется массив индикаторных переменных, показывающих где NULL величины, и всё генерится автоматом. Получили класс - можем использовать шаблоны. Результат - все очень хорошо структарировано, и в случае изменения структуры таблиц - генерится за 1 секунду. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.10.2003, 10:06 |
|
||
|
Embedded SQL via ODBC
|
|||
|---|---|---|---|
|
#18+
о, а я тоже код генерирую. код кончно не такой понятный, но в него смотреть не надо (само работает). // Babylon C++ Generator // C++ generated for Application TESTPRG // // Date generated: 24.10.2003 // Time generated: 11:34:56 // Generator version: HptBuildDate:020124 // Trace / Comments: Dictionary(false false false false ) / false #define SQLDB2_H #include <fcwrcl.h> EXEC SQL INCLUDE SQLCA; struct rcdXXX_ : public MSQLRecord { SQLCHA EZE1_ ; // HHH --> EZE1_ rcdXXX_ () : MSQLRecord ( "XXX" , 14 ) , EZE1_ ( *this , Leaf , 1, 0, 0, 14 ) {}; }; EXEC SQL BEGIN DECLARE SECTION; struct { short len; unsigned char data[10]; } *hvXXX_EZE1_; short *nidXXX_EZE1_; EXEC SQL END DECLARE SECTION; class appTESTPRG_ : public FCWMainApp { private: enum { cs_TESTAPP_MF_ = 0 } CtlState ; rcdXXX_ XXX_; public: appTESTPRG_ () ; ~appTESTPRG_ () ; void Start (); void fncTESTAPP_MF_ (); void fncX_ERROR_LOG_ (); void optX_ERROR_LOG_ (); }; appTESTPRG_ :: appTESTPRG_() : FCWMainApp ( "TESTPRG", NULL, NULL, ByPassKeys( ), Key :: None, NULL, InEdit :: All, NonSegmented ) { Init( key_dbms, val_db2 ); XXX_.Setup(); CtlState = cs_TESTAPP_MF_; } appTESTPRG_ :: ~appTESTPRG_() { } void appTESTPRG_ :: Start () { do { CtlMode = cm_normalFlow; switch (CtlState) { case cs_TESTAPP_MF_: fncTESTAPP_MF_(); if (CtlMode == cm_End || CtlMode == cm_Goto) continue; CtlMode = cm_End; break; default: break; } } while ( CtlMode != cm_End ); } void appTESTPRG_ :: fncTESTAPP_MF_ () { PrcPush("TESTAPP_MF_"); EZEFEC = 1; fncX_ERROR_LOG_( ); if ( CtlMode != cm_normalFlow ) { PrcPop(); return; } PrcPop(); return; } void appTESTPRG_ :: fncX_ERROR_LOG_ () { PrcPush("X_ERROR_LOG_"); XXX_.EZE1_ = "XXX"; optX_ERROR_LOG_( ); if ( CtlMode != cm_normalFlow ) { PrcPop(); return; } if ( EZEREPLY == 1 ) EZECOMIT( OPT_REPLY ); else EZECOMIT( OPT_NOREPLY ); PrcPop(); return; } void appTESTPRG_ :: optX_ERROR_LOG_ ( ) { if ( !XXX_.BeginAdd(2, NO_EXEC_TIME_BLD | NO_HOST_VAR_TABLE_NAME , 1 , 0 ) ) { XXX_.SetParm( 1, (AHVPTR) &hvXXX_EZE1_, (AHVPTR) &nidXXX_EZE1_, XXX_.EZE1_, 453, False ); EXEC SQL INSERT INTO XSXX (HHH) VALUES( :*hvXXX_EZE1_ :*nidXXX_EZE1_ ) ; XXX_.EndAdd ( &sqlca ); } } extern "C" int SYSCALL TESTPRG() { appTESTPRG_ App ; App.Start(); return(0); } // C++ Application Generation complete. elapsedTime = 0.02 secs. bytesPerSec = 130250,00 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.10.2003, 11:39 |
|
||
|
Embedded SQL via ODBC
|
|||
|---|---|---|---|
|
#18+
2 NewYear я понил - капец ODBC gardeman> db2 может грузить зяпись прямо в структуру все на db2 ну все могут грузить запись(си) прямо в структуру(ры) через (массив)sqlda. /* чем я занимаюсь тоже, я писал пример с insert, так как он первый попался для цикла тоже с fetch тоже есть */ я почти уверен, если ты посмотришь текст после препроцессора db2 там будет такая структура. ;)) хотя как у db2 - легче и понятнее, чем явно трахаться с sqlda ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2003, 06:31 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=32300578&tid=2035860]: |
0ms |
get settings: |
6ms |
get forum list: |
12ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
34ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
32ms |
get tp. blocked users: |
1ms |
| others: | 218ms |
| total: | 317ms |

| 0 / 0 |
