Numeric и MSSQL2k проблема

Тема в разделе "WASM.WIN32", создана пользователем Kvazimoda, 8 сен 2004.

  1. Kvazimoda

    Kvazimoda New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2004
    Сообщения:
    21
    Адрес:
    Russia
    Может кто сталкивался с проблемой следующего характера:

    Я передаю в mssql запрос следущего вида

    "update Table1 set Table1.Opt = ?

    where Table1.Price = 5"

    Передается это в функцию SQLPrepare.



    Далее привязываю параметр:

    invoke SQLBindParameter, hStmt, 1, SQL_PARAM_INPUT, SQL_С_NUMERIC, SQL_NUMERIC, 13, 2, offset Numeric_Var, sizeof Numeric_Var, offset TempVar



    Numeric_Var - Это структура вида:

    DB_NUMERIC struct

    precision db ?

    scale db ?

    sign db ?

    val db SQL_MAX_NUMERIC_LEN dup(?)

    ends

    DB_NUMERIC ends



    В Numeric_Var для тестовых целей я записываю:

    mov dword ptr [Numeric_Var.val], 11111111

    mov byte ptr [Numeric_Var.scale], 3

    mov byte ptr [Numeric_Var.sign], 1

    т.е. число 11111.111



    После SQLExecute получается, что в нужных записях находится не 11111.111, а 11111111.



    Как с этим боротся? Или это глюк MS SQL Server'а???

    Заранее спасибо!
     
  2. Zauberer

    Zauberer New Member

    Публикаций:
    0
    Регистрация:
    22 авг 2003
    Сообщения:
    11
    Адрес:
    Russia
    Хммм... Такой вопрос..

    А тип NUMERIC разве поддерживает вещественные числа?

    Я вот попробовал - он тока целые вставляет.

    Причем не только в MSSQL, но и в других базах.

    Попробуй поменять тип столбца.
     
  3. Zauberer

    Zauberer New Member

    Публикаций:
    0
    Регистрация:
    22 авг 2003
    Сообщения:
    11
    Адрес:
    Russia
    Блин, стормозил..

    Короче, ты когда таблицу создавал, какой запрос делал?

    Ты указывал сколько знаков после запятой нужно хранить? По умолчанию он хранит 0 знаков после запятой, поэтому надо вручную указывать.

    ..

    Или тут все правильно указано?
     
  4. Kvazimoda

    Kvazimoda New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2004
    Сообщения:
    21
    Адрес:
    Russia
    Да нет, все правилно в свойствах таблицы нужное мне поле является типом NUMERIC(13,3)
     
  5. Zauberer

    Zauberer New Member

    Публикаций:
    0
    Регистрация:
    22 авг 2003
    Сообщения:
    11
    Адрес:
    Russia
    Хех.. У меня тоже другую фигню записывает, но не так, как у тебя.

    Ты не можешь показать полный исходник? Чтоб мы работали над один и тем же. Может, сообразим..
     
  6. Kvazimoda

    Kvazimoda New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2004
    Сообщения:
    21
    Адрес:
    Russia
    Вот исходник. Я пишу, используя RadAsm, так что если он у тебя тоже есть: распаковываешь, и компилишь. Только исправь строку соединения (conString) и запрос (UpdEntryQuery)



    З.Ы. Интересно узнать чего у тебя за фигню вставляет!

    [​IMG] _1063808715__ODBCTest.zip
     
  7. Zauberer

    Zauberer New Member

    Публикаций:
    0
    Регистрация:
    22 авг 2003
    Сообщения:
    11
    Адрес:
    Russia
    Хмм.. У меня выдает такое же.. Будем смотреть.. Скорее всего это не глюк сервера, просто что-то не так делается..

    Кстати, он у тебя вываливается в Exception при исполнении процедуры ODBCDisconnectFromDB.

    Где именно я пока не понял (тока открыл..)
     
  8. Zauberer

    Zauberer New Member

    Публикаций:
    0
    Регистрация:
    22 авг 2003
    Сообщения:
    11
    Адрес:
    Russia
    А ну да, конечно..

    По поводу ODBCDisconnectFromDB.

    Тебе ж надо SQLDisconnect делать для соединения, а не для hEnv! Кроме того, сначала закрывают соединение, а уж потом освобождают hEnv.

    Короче, тебе надо написать так:

    ODBCDisconnectFromDB proc hEnv:lol: WORD, hCon:lol: WORD

    mov eax, dword ptr [hCon]

    test eax, eax

    jz @F

    invoke SQLDisconnect, eax

    invoke SQLFreeHandle, SQL_HANDLE_DBC, eax



    @@:

    mov eax, dword ptr [hEnv]

    test eax, eax

    jz @F



    invoke SQLFreeHandle, SQL_HANDLE_ENV, eax

    @@:

    ret

    ODBCDisconnectFromDB endp
     
  9. Kvazimoda

    Kvazimoda New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2004
    Сообщения:
    21
    Адрес:
    Russia
    Это я выдрал из своего большого проекта и подправил на скорую руку. Может чего не исправил. Вечером дома посмотрю, выложу исправленную версию! Если разберешься почему не так в mssql грузится напиши.
     
  10. Zauberer

    Zauberer New Member

    Публикаций:
    0
    Регистрация:
    22 авг 2003
    Сообщения:
    11
    Адрес:
    Russia
    Хмм.. А где обещанная исправленная версия? :)

    Я тут порылся по MSDN, нашел описание этого бага, симптомы совпадают и вот такую фразу (передаю общий смысл):

    Microsoft подтвреждает наличие ошибки при работе с ODBC-драйверами для MS SQL Server.

    .. (no comments)

    Хотя, можь, они уже исправили этот баг, а у нас ошибка еще в чем-нибудь. Но я даже отладчиком проходился - вроде все как надо..

    ..

    [offtop извиняте ради Бога, не сдержался]

    Если не секрет, а что за большой проект такой? У меня что-то совсем нет идей, тем более на ASM (одна Java на ум лезет), а тут большой проект, да еще и с ODBC+MSSQL!

    Хотя бы в общих чертах - буду знать в каком направлении думать. :)

    [/offtop]
     
  11. Kvazimoda

    Kvazimoda New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2004
    Сообщения:
    21
    Адрес:
    Russia
    Это дошлепок к 1С:Бухгалтерия, что бы самому проводить документы.
     
  12. Kvazimoda

    Kvazimoda New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2004
    Сообщения:
    21
    Адрес:
    Russia
    А где именно это в MSDN написано? Чего-то я не могу найти. Хочется почитать оригинал.
     
  13. Zauberer

    Zauberer New Member

    Публикаций:
    0
    Регистрация:
    22 авг 2003
    Сообщения:
    11
    Адрес:
    Russia
    Оба на!

    Я решил эту проблемку!!

    Похоже, в MSDN это я не то глянул или уже пофиксили.

    Пришлось перелопатить MSDN, найти примеры работы с NUMERIC через ODBC, потом переводил с VC++ на MASM, хотя в итоге оказалось нужно лишь пару строчек. Короче, после SQLBindParameter добавляешь строки:
    Код (Text):
    1.  
    2. invoke SQLGetStmtAttr, hStmtSum,SQL_ATTR_APP_PARAM_DESC, addr hDesc, 0, NULL
    3.  
    4. invoke SQLSetDescField, hDesc, 1, SQL_DESC_TYPE, SQL_C_NUMERIC, 0
    5.  
    6. invoke SQLSetDescField, hDesc, 1, SQL_DESC_PRECISION, 13, 0
    7.  
    8. invoke SQLSetDescField, hDesc, 1, SQL_DESC_SCALE, 3, 0
    9.  
    10. invoke SQLSetDescField, hDesc, 1, SQL_DESC_DATA_PTR, addr TestNum, 0
    11.  


    где hDesc объявлена как

    hDesc dd ?



    Вот какой комментарий написан к эти строчкам в MSDN:

    Modify the fields in the implicit application parameter descriptor



    Честно говоря, я пока не полностью разобрался что и как, но все работает! Проверено и перепроверено. :)

    Попробуй у себя. Если не получится - выложу весь код.

    Ну, а если это действительно помоголо - будешь должен.

    Шутка. :)
     
  14. Zauberer

    Zauberer New Member

    Публикаций:
    0
    Регистрация:
    22 авг 2003
    Сообщения:
    11
    Адрес:
    Russia
    Если получится - черкни тут пару строк - типа подтвреждение. А то, может, не в этом дело..
     
  15. Kvazimoda

    Kvazimoda New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2004
    Сообщения:
    21
    Адрес:
    Russia
    Спасибо! Пашет! Я тоже пробовал через

    invoke SQLGetStmtAttr, hStmtSum,SQL_ATTR_APP_PARAM_DESC, addr hDesc, 0, NULL



    invoke SQLSetDescField, hDesc, 1, SQL_DESC_TYPE, SQL_C_NUMERIC, 0



    invoke SQLSetDescField, hDesc, 1, SQL_DESC_PRECISION, 13, 0



    invoke SQLSetDescField, hDesc, 1, SQL_DESC_SCALE, 3, 0



    invoke SQLSetDescField, hDesc, 1, SQL_DESC_DATA_PTR, addr TestNum, 0

    но при этом убирал SQLBindParameter.

    З.Ы. А лучше еще и вот так:

    invoke SQLSetDescField, hDesc, 1, SQL_DESC_PRECISION, TestNum.precision, 0

    invoke SQLSetDescField, hDesc, 1, SQL_DESC_SCALE, TestNum.scale, 0

    вместо

    invoke SQLSetDescField, hDesc, 1, SQL_DESC_PRECISION, 13, 0

    invoke SQLSetDescField, hDesc, 1, SQL_DESC_SCALE, 3, 0