|
DB2, BLOB и "волшебные числа"
|
|||
---|---|---|---|
#18+
Напоролся я на такую проблему - DB2 (UDB 8.1 под Windows без FP, FP4,FP5) отказывалась записывать в поле BLOB файлы определенного размера. Прямо "волшебные числа" какие-то. Эксперименты позволили выявить интересную закономерность. Имеем БД с таблицей: TABLE QQQ ID INT NOT NULL FILE BLOB(2000M) (впрочем, размер поля не играет никакой роли) Создаем в таблице новую запись, используя С++ неважно какой версии, и EMBEDED SQL с препроцессором и BIND-ом. В секции описания две переменных: Id, которая int, и b, которая есть BLOB для работы с файлом на чтение. делаем EXEC SQL INSERT INTO QQQ VALUES(:Id,:b); Если до этой инструкции выполнялся любой оператор SQL (неважно, SELECT, DELETE, COMMIT или еще чего), а размер файла удовлетворяет формуле size%61436==61299, то опаньки - приложение отсоединяется от DB2 со всеми вытекающими для следующего оператора SQL. Текущая транзакция откатывается. Что интересно, если к переменной b дорисовать NULL индикатор, то "волшебный" остаток от деления становится 61297, что на два байта (размер этого самого индикатора) меньше, что позволяет обойти проблему и в зависимости от размера файла выполнять оператор с NULL индикатором или без оного. 1. Кто может прокомментировать? 2. Исправлено ли это в новых фикспаках и в версии 8.2? Виктор ... |
|||
:
Нравится:
Не нравится:
|
|||
27.05.2005, 21:07 |
|
DB2, BLOB и "волшебные числа"
|
|||
---|---|---|---|
#18+
нет там никаких волшебных чисел, грамотно привязку параметров надо выполнять. >Что интересно, если к переменной b дорисовать NULL индикатор, то ... Потому как этим добавлением ты наконец-то косвенно определяешь размер буфера передаваемых данных и все прокатывает. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2005, 10:27 |
|
DB2, BLOB и "волшебные числа"
|
|||
---|---|---|---|
#18+
adolfнет там никаких волшебных чисел, грамотно привязку параметров надо выполнять. >Что интересно, если к переменной b дорисовать NULL индикатор, то ... Потому как этим добавлением ты наконец-то косвенно определяешь размер буфера передаваемых данных и все прокатывает. Грамотно - это как? Там что, есть какой-то особый порядок привязки параметров? Насколько я помню, в доке ни слова о том, что надо что-то обязательно сделать дополнительного к следующей цепочке: - создание БД - CREATE DB - создание таблицы в оной - CREATE TABLE - создание исходника .SQX, содержащего DECLARE SECTION с переменными, которые будут параметрами и SQL оператор, использующий эти переменные в качестве параметров - прекомпиляция и BIND Если что-то необходимо еще, то это танцы с бубном вокруг ошибки, а не "грамотная привязка параметров". А ошибка эта на мой взгляд говорит лишь о том, что DB2 обламывается, покольку где-то у ней внутри что-то неправильно считается, например, количество потребных буферов. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2005, 20:48 |
|
DB2, BLOB и "волшебные числа"
|
|||
---|---|---|---|
#18+
может просто выложишь кусок исходника? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2005, 10:00 |
|
DB2, BLOB и "волшебные числа"
|
|||
---|---|---|---|
#18+
Легко. Добавлю только, что в семерке это работало без проблем. Началось именно в 8.1 1. Пущаем db2cmd Далее там CHCP 866 - Это для того, чтобы тупой DB2 нормально шпарил по русски в консоли. Правда на вывод PREP и BIND это никак не влияет. Приходится потом "декодировать" в редакторе FAR. Далее CREATE DB Test ON D: CONNECT TO Test CREATE TABLE QQQ1 (Id INT NOT NULL PRIMARY KEY, File BLOB(200M)) Теперь пишем программулину zzz.sqx ========= #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sql.h> EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; SQL TYPE IS BLOB_FILE MessFile = {0,0,SQL_FILE_READ}; long lRecId; short lobind=0; EXEC SQL END DECLARE SECTION; int main(int argc, char *argv[]){ char buf[512] = ""; int rc = 0; char ch; strcpy(MessFile.name,argv[2]); MessFile.name_length=strlen(MessFile.name); MessFile.data_length=0; EXEC SQL CONNECT TO test; lRecId=atol(argv[1]); // Этот оператор по барабану какой, лишь бы что-то было EXEC SQL COMMIT; EXEC SQL INSERT INTO qqq1 VALUES (:lRecId, :MessFile); // EXEC SQL INSERT INTO qqq1 VALUES (:lRecId, :MessFile :lobind); EXEC SQL COMMIT; if (SQLCODE){ rc = sqlaintp( buf, 512, 78, &sqlca ); if ( rc != SQLA_ERR_NOMSG ) {printf("\n%s RC=%d.\n","commit",sqlca.sqlcode); printf("%s\n",buf); } } } Далее, понятное дело PREP на zzz.sqx и BIND на zzz.bnd Параметры этих операторов ни на что не влияют. Разве что при уровне оптимизации больше нуля наблюдаются вылеты на некоторых особо крутых операторах. Но это уже совсем другая история. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.06.2005, 20:44 |
|
|
start [/forum/topic.php?fid=43&fpage=145&tid=1605880]: |
0ms |
get settings: |
8ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
32ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
38ms |
get tp. blocked users: |
2ms |
others: | 284ms |
total: | 398ms |
0 / 0 |