利用VC++獲取異構型資料庫庫結構資訊 (轉)
利用VC++獲取異構型資料庫庫結構資訊 (轉)[@more@]
空軍電訊工程學院室 萬映輝 邸曉奕
摘 要:本文在介紹OC技術的基礎上,將MFC和ODBC 結合起來建立了兩個自定義 類,
實現了對任意異構型資料庫庫結構資訊的獲取。
關鍵字:ODBC,MFC,異構型資料庫,記錄集
一. 問題的提出
隨著資料庫技術在各個應用領域的迅速發展,市場上推出了多種資料庫,為了充分利用資源,實現資訊共享,以便能對異構型資料庫實現透明的訪問(包括資料查詢、和等功能),作者開發了異構型資料庫通訊平臺。在平臺的研製過程中,獲取各種異構型資料庫的結構資訊是進行資料訪問的前提。作者以VC++5.0為開發語言,利用ODBC實現了這一關鍵技術。
二. ODBC技術介紹
ODBC技術是指開放性資料庫連線技術,該技術使應用無需關心資料來源來自何種DBMS,利用其標準介面實現與資料來源之間的資料交換。傳統的ODBC是利用高階語言(如C語言)ODBC的API來實現。應用程式要求程式管理器和每個驅動程式為ODBC環境、每個連線以及每個語句分配資訊空間,並返回指向各個儲存區的控制程式碼供其呼叫。ODBC介面定義了三種控制程式碼型別:
環境控制程式碼:為全程資訊標識儲存,包括有效連線控制程式碼及當前活動連線控制程式碼。ODBC將環境控制程式碼定義為HENV型別的變數。應用程式使用單一環境控制程式碼,它必須在連線到資料來源前請求該控制程式碼。
連線控制程式碼:為特定連線的資訊標識了記憶體儲存。ODBC將連線控制程式碼定義為HDBC型別。應用程式必須在連線到資料來源前請求連線控制程式碼。每個連線控制程式碼與環境控制程式碼有關。然而,環境控制程式碼可以有多個與其有關的連線控制程式碼。
語句控制程式碼:為SQL語句資訊標識記憶體儲存。ODBC將語句控制程式碼定義為HSTMT型別變數。應用程式必須在提交SQL請求之前請求語句控制程式碼。每個語句控制程式碼與一個連線控制程式碼有關。然而,每個連線控制程式碼可以有多個與其相關的語句控制程式碼。
下面以C語言為例說明傳統ODBC程式設計的一般過程。
1、 環境申請,分配環境控制程式碼
HENV henv;
SQLAllocEnv(&henv);
說明:分配一個環境控制程式碼,支援一個或多個資料來源連線。
2、 連線申請,分配連線控制程式碼
HDBC hdbc;
SQLAllocConnect(henv,&hdbc);
說明:一個連線控制程式碼對應一個資料來源,可以有多個連線控制程式碼。
3、 連線資料來源,用連線控制程式碼連線到資料來源
SQLConnect(hdbc,...);
說明:以對話方塊方式獲取註冊資訊,並連線資料來源。
4、 語句申請,分配語句控制程式碼
SQLAllocStmt(hdbc,&hstmt);
說明:獲得語句控制程式碼,以便SQL語句。
5、 執行SQL語句
SQLExecDirect(hstmt,SQLStatement,..);
說明:利用語句控制程式碼,執行SQL語句。
6、 釋放所有資源
SQLfreeStemt(hstmst,...); //釋放語句控制程式碼
SQLDinnect(hdbc); //斷開連線
SQLFreeConnect(hdbc); //釋放當前資料庫連線控制程式碼
SQLFreeEnv(henv); //釋放環境控制程式碼
三. 利用VC++和ODBC技術獲取異構型資料庫結構資訊
傳統的ODBC程式設計過程比較複雜,各種引數不易理解,且直接獲取返回的資料較困難。VC++ 5.0的MFC類庫對ODBC的API進行封裝,部分簡化了ODBC程式設計(尤其是對資料庫記錄集的操作),但單純利用MFC類獲取異構型資料庫的結構資訊仍然比較困難,因此需要將MFC和傳統ODBC API程式設計結合起來。作者利用ODBC介面過載了MFC中CRecordset類的部分成員函式,建立CTable和CColumns類。利用這兩個新建立的類,可以很方便的獲取異構型資料庫結構資訊。
下面就是關於CTable和Ccolumns類的定義:
class CTable : public CRecordset
{
virtual CString GetDefaultConnect() { return ""; }
virtual CString GetDefaultSQL() { return ""; }
public:
CTable(CDatabase* pDatabase);
BOOL Open(LPCSTR pszTableQualifier = NULL,
LPCSTR pszTableOwner = NULL,
LPCSTR pszTableName = NULL,
LPCSTR pszTableType = NULL,
UINT nOpenType = forwardOnly);
CString m_strTableQualifier;
CString m_strTableOwner;
CString m_strTableName;
CString m_strTableType;
CString m_strRemarks;
virtual void DoField(CFieldExchange*);
};
class CColumns : public CRecordset
{
virtual CString GetDefaultConnect() { return ""; }
virtual CString GetDefaultSQL() { return ""; }
public:
CColumns(CDatabase* pDatabase);
BOOL Open(LPCSTR pszTableQualifier = NULL,
LPCSTR pszTableOwner = NULL,
LPCSTR pszTableName = NULL,
LPCSTR pszColumnName = NULL,
UINT nOpenType = forwardOnly);
CString m_strTableQualifier;
CString m_strTableOwner;
CString m_strTableName;
CString m_strColumnName;
int m_nDataType;
CString m_strTypeName;
long m_nPrecision;
long m_nLength;
int m_nScale;
int m_nRadix;
int m_fNullable;
CString m_strRemarks;
virtual void DoFieldExchange(CFieldExchange*);
};
BOOL CColumns::Open(LPCSTR pszTableQualifier,
LPCSTR pszTableOwner,LPCSTR pszTableName,LPCSTR pszColumnName,
UINT nOpenType)
{
RETCODE nRetCode;
U bFunctionExists;
//檢驗是否支援SQLColumns函式
AFX_SQL_SYNC(::SQLGetFunctions(m_pDatabase->m_hdbc,
SQL_API_SQLCOLUMNS,&bFunctionExists));
if (!Check(nRetCode) || !bFunctionExists)
{
if (!bFunctionExists)
TRACE(_T("SQLColumns 不支援n"));
return FALSE;
}
//設定緩衝區狀態,分配語句控制程式碼
SetState(nOpenType,NULL,readOnly);
if (!AllocHstmt())
return FALSE;
TRY
{
OnSetOptions(m_hstmt);
AllocStatusArrays();
// 呼叫ODBC的SQLColumns函式
AFX_ODBC_CALL(::SQLColumns(m_hstmt,
(UCHAR FAR*)pszTableQualifier,SQL_NTS,
(UCHAR FAR*)pszTableOwner,SQL_NTS,
(UCHAR FAR*)pszTableName,SQL_NTS,
(UCHAR FAR*)pszColumnName,SQL_NTS));
if (!Check(nRetCode))
ThrowDBException(nRetCode,m_hstmt);
// 分配記憶體,填寫資訊
AllocAndCacheFieldInfo();
AllocRowset();
MoveNext();
m_bBOF = m_bEOF;
}
//異常資訊的捕獲
CATCH_ALL(e)
{
Close();
THROW_LAST();
}
END_CATCH_ALL
return TRUE;
}
//獲取記錄集資訊
void CColumns::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX,_T("TABLE_QUALIFIER"),m_strTableQualifier);
RFX_Text(pFX,_T("TABLE_OWNER"),m_strTableOwner);
RFX_Text(pFX,_T("TABLE_NAME"),m_strTableName);
RFX_Text(pFX,_T("COLUMN_NAME"),m_strColumnName);
RFX_Int(pFX,_T("DATA_TYPE"),m_nDataType);
RFX_Text(pFX,_T("TYPE_NAME"),m_strTypeName);
RFX_Long(pFX,_T("PRECISION"),m_nPrecision);
RFX_Long(pFX,_T("LENGTH"),m_nLength);
RFX_Int(pFX,_T("SCALE"),m_nScale);
RFX_Int(pFX,_T("RADIX"),m_nRadix);
RFX_Int(pFX,_T("NULLABLE"),m_fNullable);
RFX_Text(pFX,_T("REMARKS"),m_strRemarks);
}
CColumns::CColumns(CDatabase* pDatabase): CRecordset(pDatabase)
{
m_strTableQualifier = _T("");
m_strTableOwner = _T("");
m_strTableName = _T("");
m_strColumnName = _T("");
m_nDataType = 0;
m_strTypeName = _T("");
m_nPrecision = 0;
m_nLength = 0;
m_nScale = 0;
m_nRadix = 0;
m_fNullable = 0;
m_strRemarks = _T("");
m_nFields = 12;
}
CTable::CTable(CDatabase* pDatabase): CRecordset(pDatabase)
{
m_strTableQualifier = _T("");
m_strTableOwner = _T("");
m_strTableName = _T("");
m_strTableType = _T("");
m_strRemarks = _T("");
m_nFields = 5;
}
BOOL CTable::Open(LPCSTR pszTableQualifier,
LPCSTR pszTableOwner,LPCSTR pszTableName,LPCSTR pszTableType,
UINT nOpenType)
{
RETCODE nRetCode;
UWORD bFunctionExists;
//檢驗是否支援SQLTables 函式
AFX_SQL_SYNC(::SQLGetFunctions(m_pDatabase->m_hdbc,
SQL_API_SQLTABLES,&bFunctionExists));
if (!Check(nRetCode) || !bFunctionExists)
{
if (!bFunctionExists)
TRACE(_T("SQLTables 不支援n"));
return FALSE;
}
//設定緩衝區狀態,分配語句控制程式碼
SetState(nOpenType,NULL,readOnly);
if (!AllocHstmt())
return FALSE;
TRY
{
OnSetOptions(m_hstmt);
AllocStatusArrays();
//呼叫 ODBC的SQLTables函式
AFX_ODBC_CALL(::SQLTables(m_hstmt,
(UCHAR FAR*)pszTableQualifier,SQL_NTS,
(UCHAR FAR*)pszTableOwner,SQL_NTS,
(UCHAR FAR*)pszTableName,SQL_NTS,
(UCHAR FAR*)pszTableType,SQL_NTS));
if (!Check(nRetCode))
ThrowDBException(nRetCode,m_hstmt);
// 分配記憶體,填寫資訊
AllocAndCacheFieldInfo();
AllocRowset();
MoveNext();
m_bBOF = m_bEOF;
}
//異常資訊的捕獲
CATCH_ALL(e)
{
Close();
THROW_LAST();
}
END_CATCH_ALL
return TRUE;
}
void CTable::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX,_T("TABLE_QUALIFIER"),m_strTableQualifier);
RFX_Text(pFX,_T("TABLE_OWNER"),m_strTableOwner);
RFX_Text(pFX,_T("TABLE_NAME"),m_strTableName);
RFX_Text(pFX,_T("TABLE_TYPE"),m_strTableType);
RFX_Text(pFX,_T("REMARKS"),m_strRemarks);
}
以上兩個類對CRecordset的Open和DoFieldExchange函式進行了過載。應用程式可以在需要時建立CTable或Ccolumns類,並呼叫OPEN成員函式建立相應的表結構和欄位結構記錄集。接下來就可以透過下列函式來遍歷異構型資料庫的結構資訊了。
Void CRecordset::MoveFirst(); //移到第一條記錄
Void CRecordset::MoveLast(); //移到最後一條記錄
Void CRecordset::MovePrev(); //移到前一條記錄
Void CRecordset::MoveNext(); //移到後一條記錄
BOOL CRecordset::IsBOF(); //判斷是否到達第一條記錄前
BOOL CRecordset::IsEOF(); //判斷是否到達最後一條記錄後
四、結束語
利用自定義的CTable和Ccolumns類,應用程式能獲取任何異構型資料庫庫結構資訊。根據獲得的資訊可以方便的對未知資料庫進行相應的操作。若將CTable和Ccolumns類與文件類、視類結合起來,就可以在視窗裡以一定的方式顯示結構資訊。作者利用以上技術在異構型資料庫通訊平臺上成功實現了對各種異構型資料庫庫結構資訊的獲取。
參考文獻:
Mircosoft 《ODBC 2.0 Programmer's Reference and SDK Gu》
利用VC++獲取異構型資料庫庫結構資訊
利用VC++獲取異構型庫結構資訊
空軍電訊工程學院室 萬映輝 邸曉奕
摘 要:本文在介紹OC技術的基礎上,將MFC和ODBC 結合起來建立了兩個自定義 類,
實現了對任意異構型資料庫庫結構資訊的獲取。
關鍵字:ODBC,MFC,異構型資料庫,記錄集
一. 問題的提出
隨著資料庫技術在各個應用領域的迅速發展,市場上推出了多種資料庫,為了充分利用資源,實現資訊共享,以便能對異構型資料庫實現透明的訪問(包括資料查詢、和等功能),作者開發了異構型資料庫通訊平臺。在平臺的研製過程中,獲取各種異構型資料庫的結構資訊是進行資料訪問的前提。作者以VC++5.0為開發語言,利用ODBC實現了這一關鍵技術。
二. ODBC技術介紹
ODBC技術是指開放性資料庫連線技術,該技術使應用無需關心資料來源來自何種DBMS,利用其標準介面實現與資料來源之間的資料交換。傳統的ODBC是利用高階語言(如C語言)ODBC的API來實現。應用程式要求程式管理器和每個驅動程式為ODBC環境、每個連線以及每個語句分配資訊空間,並返回指向各個儲存區的控制程式碼供其呼叫。ODBC介面定義了三種控制程式碼型別:
環境控制程式碼:為全程資訊標識儲存,包括有效連線控制程式碼及當前活動連線控制程式碼。ODBC將環境控制程式碼定義為HENV型別的變數。應用程式使用單一環境控制程式碼,它必須在連線到資料來源前請求該控制程式碼。
連線控制程式碼:為特定連線的資訊標識了記憶體儲存。ODBC將連線控制程式碼定義為HDBC型別。應用程式必須在連線到資料來源前請求連線控制程式碼。每個連線控制程式碼與環境控制程式碼有關。然而,環境控制程式碼可以有多個與其有關的連線控制程式碼。
語句控制程式碼:為SQL語句資訊標識記憶體儲存。ODBC將語句控制程式碼定義為HSTMT型別變數。應用程式必須在提交SQL請求之前請求語句控制程式碼。每個語句控制程式碼與一個連線控制程式碼有關。然而,每個連線控制程式碼可以有多個與其相關的語句控制程式碼。
下面以C語言為例說明傳統ODBC程式設計的一般過程。
1、 環境申請,分配環境控制程式碼
HENV henv;
SQLAllocEnv(&henv);
說明:分配一個環境控制程式碼,支援一個或多個資料來源連線。
2、 連線申請,分配連線控制程式碼
HDBC hdbc;
SQLAllocConnect(henv,&hdbc);
說明:一個連線控制程式碼對應一個資料來源,可以有多個連線控制程式碼。
3、 連線資料來源,用連線控制程式碼連線到資料來源
SQLConnect(hdbc,...);
說明:以對話方塊方式獲取註冊資訊,並連線資料來源。
4、 語句申請,分配語句控制程式碼
SQLAllocStmt(hdbc,&hstmt);
說明:獲得語句控制程式碼,以便SQL語句。
5、 執行SQL語句
SQLExecDirect(hstmt,SQLStatement,..);
說明:利用語句控制程式碼,執行SQL語句。
6、 釋放所有資源
SQLfreeStemt(hstmst,...); //釋放語句控制程式碼
SQLDinnect(hdbc); //斷開連線
SQLFreeConnect(hdbc); //釋放當前資料庫連線控制程式碼
SQLFreeEnv(henv); //釋放環境控制程式碼
三. 利用VC++和ODBC技術獲取異構型資料庫結構資訊
傳統的ODBC程式設計過程比較複雜,各種引數不易理解,且直接獲取返回的資料較困難。VC++ 5.0的MFC類庫對ODBC的API進行封裝,部分簡化了ODBC程式設計(尤其是對資料庫記錄集的操作),但單純利用MFC類獲取異構型資料庫的結構資訊仍然比較困難,因此需要將MFC和傳統ODBC API程式設計結合起來。作者利用ODBC介面過載了MFC中CRecordset類的部分成員函式,建立CTable和CColumns類。利用這兩個新建立的類,可以很方便的獲取異構型資料庫結構資訊。
下面就是關於CTable和Ccolumns類的定義:
class CTable : public CRecordset
{
virtual CString GetDefaultConnect() { return ""; }
virtual CString GetDefaultSQL() { return ""; }
public:
CTable(CDatabase* pDatabase);
BOOL Open(LPCSTR pszTableQualifier = NULL,
LPCSTR pszTableOwner = NULL,
LPCSTR pszTableName = NULL,
LPCSTR pszTableType = NULL,
UINT nOpenType = forwardOnly);
CString m_strTableQualifier;
CString m_strTableOwner;
CString m_strTableName;
CString m_strTableType;
CString m_strRemarks;
virtual void DoField(CFieldExchange*);
};
class CColumns : public CRecordset
{
virtual CString GetDefaultConnect() { return ""; }
virtual CString GetDefaultSQL() { return ""; }
public:
CColumns(CDatabase* pDatabase);
BOOL Open(LPCSTR pszTableQualifier = NULL,
LPCSTR pszTableOwner = NULL,
LPCSTR pszTableName = NULL,
LPCSTR pszColumnName = NULL,
UINT nOpenType = forwardOnly);
CString m_strTableQualifier;
CString m_strTableOwner;
CString m_strTableName;
CString m_strColumnName;
int m_nDataType;
CString m_strTypeName;
long m_nPrecision;
long m_nLength;
int m_nScale;
int m_nRadix;
int m_fNullable;
CString m_strRemarks;
virtual void DoFieldExchange(CFieldExchange*);
};
BOOL CColumns::Open(LPCSTR pszTableQualifier,
LPCSTR pszTableOwner,LPCSTR pszTableName,LPCSTR pszColumnName,
UINT nOpenType)
{
RETCODE nRetCode;
U bFunctionExists;
//檢驗是否支援SQLColumns函式
AFX_SQL_SYNC(::SQLGetFunctions(m_pDatabase->m_hdbc,
SQL_API_SQLCOLUMNS,&bFunctionExists));
if (!Check(nRetCode) || !bFunctionExists)
{
if (!bFunctionExists)
TRACE(_T("SQLColumns 不支援n"));
return FALSE;
}
//設定緩衝區狀態,分配語句控制程式碼
SetState(nOpenType,NULL,readOnly);
if (!AllocHstmt())
return FALSE;
TRY
{
OnSetOptions(m_hstmt);
AllocStatusArrays();
// 呼叫ODBC的SQLColumns函式
AFX_ODBC_CALL(::SQLColumns(m_hstmt,
(UCHAR FAR*)pszTableQualifier,SQL_NTS,
(UCHAR FAR*)pszTableOwner,SQL_NTS,
(UCHAR FAR*)pszTableName,SQL_NTS,
(UCHAR FAR*)pszColumnName,SQL_NTS));
if (!Check(nRetCode))
ThrowDBException(nRetCode,m_hstmt);
// 分配記憶體,填寫資訊
AllocAndCacheFieldInfo();
AllocRowset();
MoveNext();
m_bBOF = m_bEOF;
}
//異常資訊的捕獲
CATCH_ALL(e)
{
Close();
THROW_LAST();
}
END_CATCH_ALL
return TRUE;
}
//獲取記錄集資訊
void CColumns::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX,_T("TABLE_QUALIFIER"),m_strTableQualifier);
RFX_Text(pFX,_T("TABLE_OWNER"),m_strTableOwner);
RFX_Text(pFX,_T("TABLE_NAME"),m_strTableName);
RFX_Text(pFX,_T("COLUMN_NAME"),m_strColumnName);
RFX_Int(pFX,_T("DATA_TYPE"),m_nDataType);
RFX_Text(pFX,_T("TYPE_NAME"),m_strTypeName);
RFX_Long(pFX,_T("PRECISION"),m_nPrecision);
RFX_Long(pFX,_T("LENGTH"),m_nLength);
RFX_Int(pFX,_T("SCALE"),m_nScale);
RFX_Int(pFX,_T("RADIX"),m_nRadix);
RFX_Int(pFX,_T("NULLABLE"),m_fNullable);
RFX_Text(pFX,_T("REMARKS"),m_strRemarks);
}
CColumns::CColumns(CDatabase* pDatabase): CRecordset(pDatabase)
{
m_strTableQualifier = _T("");
m_strTableOwner = _T("");
m_strTableName = _T("");
m_strColumnName = _T("");
m_nDataType = 0;
m_strTypeName = _T("");
m_nPrecision = 0;
m_nLength = 0;
m_nScale = 0;
m_nRadix = 0;
m_fNullable = 0;
m_strRemarks = _T("");
m_nFields = 12;
}
CTable::CTable(CDatabase* pDatabase): CRecordset(pDatabase)
{
m_strTableQualifier = _T("");
m_strTableOwner = _T("");
m_strTableName = _T("");
m_strTableType = _T("");
m_strRemarks = _T("");
m_nFields = 5;
}
BOOL CTable::Open(LPCSTR pszTableQualifier,
LPCSTR pszTableOwner,LPCSTR pszTableName,LPCSTR pszTableType,
UINT nOpenType)
{
RETCODE nRetCode;
UWORD bFunctionExists;
//檢驗是否支援SQLTables 函式
AFX_SQL_SYNC(::SQLGetFunctions(m_pDatabase->m_hdbc,
SQL_API_SQLTABLES,&bFunctionExists));
if (!Check(nRetCode) || !bFunctionExists)
{
if (!bFunctionExists)
TRACE(_T("SQLTables 不支援n"));
return FALSE;
}
//設定緩衝區狀態,分配語句控制程式碼
SetState(nOpenType,NULL,readOnly);
if (!AllocHstmt())
return FALSE;
TRY
{
OnSetOptions(m_hstmt);
AllocStatusArrays();
//呼叫 ODBC的SQLTables函式
AFX_ODBC_CALL(::SQLTables(m_hstmt,
(UCHAR FAR*)pszTableQualifier,SQL_NTS,
(UCHAR FAR*)pszTableOwner,SQL_NTS,
(UCHAR FAR*)pszTableName,SQL_NTS,
(UCHAR FAR*)pszTableType,SQL_NTS));
if (!Check(nRetCode))
ThrowDBException(nRetCode,m_hstmt);
// 分配記憶體,填寫資訊
AllocAndCacheFieldInfo();
AllocRowset();
MoveNext();
m_bBOF = m_bEOF;
}
//異常資訊的捕獲
CATCH_ALL(e)
{
Close();
THROW_LAST();
}
END_CATCH_ALL
return TRUE;
}
void CTable::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX,_T("TABLE_QUALIFIER"),m_strTableQualifier);
RFX_Text(pFX,_T("TABLE_OWNER"),m_strTableOwner);
RFX_Text(pFX,_T("TABLE_NAME"),m_strTableName);
RFX_Text(pFX,_T("TABLE_TYPE"),m_strTableType);
RFX_Text(pFX,_T("REMARKS"),m_strRemarks);
}
以上兩個類對CRecordset的Open和DoFieldExchange函式進行了過載。應用程式可以在需要時建立CTable或Ccolumns類,並呼叫OPEN成員函式建立相應的表結構和欄位結構記錄集。接下來就可以透過下列函式來遍歷異構型資料庫的結構資訊了。
Void CRecordset::MoveFirst(); //移到第一條記錄
Void CRecordset::MoveLast(); //移到最後一條記錄
Void CRecordset::MovePrev(); //移到前一條記錄
Void CRecordset::MoveNext(); //移到後一條記錄
BOOL CRecordset::IsBOF(); //判斷是否到達第一條記錄前
BOOL CRecordset::IsEOF(); //判斷是否到達最後一條記錄後
四、結束語
利用自定義的CTable和Ccolumns類,應用程式能獲取任何異構型資料庫庫結構資訊。根據獲得的資訊可以方便的對未知資料庫進行相應的操作。若將CTable和Ccolumns類與文件類、視類結合起來,就可以在視窗裡以一定的方式顯示結構資訊。作者利用以上技術在異構型資料庫通訊平臺上成功實現了對各種異構型資料庫庫結構資訊的獲取。
參考文獻:
Mircosoft 《ODBC 2.0 Programmer's Reference and SDK Gu》
利用VC++獲取異構型資料庫庫結構資訊
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988224/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 資料庫結構操作 (轉)資料庫
- 資料庫資料變成樹型結構資料庫
- 比較兩個資料庫的表結構差異(轉)資料庫
- 異構資料庫訪問資料庫
- jdbcTemplate 獲取資料表結構JDBC
- 獲取資料庫bak檔案資訊資料庫
- Oracle 資料庫 結構Oracle資料庫
- R:連結KEGG資料庫獲取更多描述資訊資料庫
- javascript 資料型態/結構驗證庫 : SkeletonsJavaScript
- 利用AUDIT檢視資料庫表結構變化資料庫
- mysql資料庫-資料結構MySql資料庫資料結構
- 異構資料庫之間資料作業資料庫
- 【轉】通過sql語句獲取資料庫的基本資訊SQL資料庫
- Activiti資料庫表結構資料庫
- Dedecms 資料庫 結構分析資料庫
- IMDB的資料庫結構資料庫
- QC資料庫表結構資料庫
- database資料庫的資料結構Database資料庫資料結構
- 如何用PLSQL匯出資料庫存表結構資訊SQL資料庫
- PostgreSQL 資料庫學習 - 1.資料庫體系結構之儲存結構SQL資料庫
- 配置ORACLE資料庫到達夢資料庫的異構DBLINKOracle資料庫
- 資料庫結構的優化資料庫優化
- Oracle資料庫體系結構Oracle資料庫
- 簡述oracle資料庫結構Oracle資料庫
- 管理資料庫儲存結構資料庫
- Oracle 8i資料庫體系結構(轉)Oracle資料庫
- 樹型結構資料在資料庫基本表中的儲存及維護 (轉)資料庫
- Golang 針對 MySQL 資料庫表結構的差異 SQL 工具GolangMySql資料庫
- wdcp環境innodb結構mysql資料庫表異常需要重建MySql資料庫
- 利用反射讀取資料庫資料反射資料庫
- 摩杜雲資料庫MySQL,破解異構資料庫遷移難題資料庫MySql
- 根據資料庫中取記錄自定義一棵樹結構 (轉)資料庫
- 異構資料庫間批量表快速複製資料庫
- 在Linux異構網路中備份MYSQL資料庫(轉)LinuxMySql資料庫
- 資料庫索引背後的資料結構資料庫索引資料結構
- (轉)怎樣才能dump資料庫的內部結構?資料庫
- 在Oracle資料庫中使用XML資料獲取業務資訊XHOracle資料庫XML
- MySQL 對比資料庫表結構MySql資料庫