Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Windows. ODBC. MDB база. Проблема с SQLColumns 
:(
    Опции темы
ПостороннимВ
Дата 14.8.2011, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 14.8.2011

Репутация: нет
Всего: нет



Коллеги, кто работал с функциями ODBC напрямую? передо мной задача - получить полное описание всех таблиц в базе MDB. Список таблиц я прекрасно получаю и обрабатываю с помощью SQLTables. Список колонок получается при помощи SQLColumns. С именами и типами данных все в порядке. А вот с признаком NOT NULL - нет! Сколько бы ни было в таблице колонок NOT NULL, для всех них возвращается NULLABLE = 1 (11 позиция) и ISNULLABLE = "YES" (18 позиция).

У гугля спрашивал - только еще 1 человек в 2006 году интересовался подобным, и ему никто не ответил....
Вот есть программка http://alekseyrybakov.narod.ru/ViewODBC.zip, так она показывает все правильно. Посмотрел таблицу импорта exe-шника - автор вроде тоже пользуется SQLColumns, включил трассировку ODBC, и потом у себя воспроизвел те же вызовы с теми же параметрами - и нифига. Правда, он получает данные из result set-а, сделав предварительно SQLBindCol, как в примере в MSDN, а я через SQLGetData, но это же непринципиально, ИМХО. Я и через SQLBindCol пробовал - то же самое, Nullable = 1, хоть тресни.

Написал тестовую прогу, она коннектится к базе db1.mdb, лежащей в текущем каталоге, создает таблицу с двумя NOT NULL колонками, и сразу же запрашивает инфу о колонках этой таблицы. Если обнаружена колонка NOT NULL, то должен выскочить MessageBox.

Я уж пробовал и Nullable вместо SQLSMALLINT определять как SQLINTEGER - все равно 1. Может, я ошибаюсь где-то в программе? У меня такое чувство, что есть какая-то хитрость, которую знают все, кроме меня, потому что с виду все просто (для меня), и я не пойму, что можно подправить в получении полей запроса, чтобы заработало.

Код

#include "stdafx.h"

#include <windows.h>
#include <sqlext.h>


int _tmain(int argc, _TCHAR* argv[])
{
    SQLHENV hSqlEnv = NULL;
    SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hSqlEnv);
    SQLSetEnvAttr(hSqlEnv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, NULL);

    SQLHDBC hDbc = NULL;
    SQLAllocHandle(SQL_HANDLE_DBC, hSqlEnv, &hDbc);
    LPWSTR lpOutConnectParams = new WCHAR[1024 + 1];
    SHORT i = 0;
    SQLRETURN ODBCcode = SQLDriverConnect(hDbc, NULL, L"Driver=Microsoft Access Driver (*.mdb);DriverId=25;FIL=MS Access;MaxBufferSize=2048;PageTimeout=5;DBQ=db1.mdb", 109, lpOutConnectParams, 1025, &i, SQL_DRIVER_NOPROMPT);
    delete[] lpOutConnectParams;
    if (ODBCcode != SQL_SUCCESS)
    {
        MessageBox(NULL, L"Connect to database failed", L"Error", MB_OK + MB_ICONERROR);
        return 1;
    }

    SQLHSTMT hStmt = NULL;
    SQLAllocStmt(hDbc, &hStmt);
    ODBCcode = SQLExecDirect(hStmt, L"CREATE TABLE TestTable (xKey SMALLINT PRIMARY KEY, xNumericValue INTEGER NOT NULL, xCharValue VARCHAR NOT NULL)", SQL_NTS);
    
    SQLColumns(hStmt, NULL, 0, NULL, 0, (SQLWCHAR*)L"TestTable", SQL_NTS, NULL, 0);
    SQLINTEGER cbColumnName, cbNullable, cbIsNullable;
    SQLSMALLINT Nullable;
    SQLCHAR* lpszColumnName = new SQLCHAR[256 + 1];
    SQLCHAR* lpszIsNullable = new SQLCHAR[256 + 1];
    while (SQLFetch(hStmt) == SQL_SUCCESS)
    {
        cbColumnName = SQL_NTS;
        cbNullable = 0;
        cbIsNullable = SQL_NTS;
        SQLGetData(hStmt, 4, SQL_C_CHAR, lpszColumnName, 256 + 1, &cbColumnName);
        SQLGetData(hStmt, 11, SQL_C_SSHORT, &Nullable, 0, &cbNullable);
        SQLGetData(hStmt, 18, SQL_C_CHAR, lpszIsNullable, 256 + 1, &cbIsNullable);
        if (!Nullable)
            MessageBoxA(NULL, (LPCSTR)lpszColumnName, "This is NOT NULL detected column", MB_OK + MB_ICONINFORMATION);
    }
    delete[] lpszColumnName;
    delete[] lpszIsNullable;

    SQLFreeStmt(hStmt, SQL_CLOSE);
    SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
    SQLDisconnect(hDbc);
    SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
    SQLFreeHandle(SQL_HANDLE_ENV, hSqlEnv);
    return 0;
}

PM MAIL   Вверх
Kirow
Дата 11.10.2011, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 1.11.2007

Репутация: нет
Всего: нет



Не могли бы привести пример кода, как с помощью SQLTables получить список таблиц БД? А то к сожалению у меня не получается...получаю пути к файлам вместо имен таблиц.

UPD:
Нашел простой и рабочий пример кода с получением таблиц...
Скопирую, на всякий случай...вдруг кому-либо понадобится
Код

SQLHSTMT hstmt; 
if (SQLAllocStmt(cdb.m_hdbc,&hstmt)==SQL_SUCCESS) 
{ 
   if (SQLTables(hstmt, NULL,0, NULL,0, NULL,0, NULL,0)==SQL_SUCCESS) 
   { 
      SQLRETURN retcode = 0; 
      char Res[128]; 
      CString ResC; 
      SQLINTEGER ResCount = 0; 
      SQLFetch(hstmt); 
      while (retcode != SQL_NO_DATA) 
      { 
         SQLGetDatahstmt,4,SQL_C_DEFAULT,&Res,128,&ResCount); 
               ResC = Res; 
               if (ResC=="TABLE") 
               { 
                  SQLGetData(hstmt,3,SQL_C_DEFAULT,&Res,128,&ResCount); 
                  m_Combo.AddString(Res); 
               } 
               retcode = SQLFetch(hstmt); 
      } 
   }; 
   SQLFreeStmt(hstmt,SQL_DROP);
}


Это сообщение отредактировал(а) Kirow - 11.10.2011, 21:17
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C++: Базы данных"
chipset

Данный форум предназначен для обсуждения вопросов прямым образом связанных с C++ и БД. Так, вопросы только по C++ следует задавать в C++:Общие вопросы а вопросы по абстрактным БД в Базах данных или в соответствующих под-форумах.

Благодарим за понимание.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, chipset.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Базы данных | Следующая тема »


 




[ Время генерации скрипта: 0.0440 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.