ADO (ActiveX Data Objects) 配合 ADOX (ADO Extensions for DDL and Security) 可在程式中動態建立 *.mdb 檔案、資料表、索引與關聯,無需預先安裝 Access。本文示範從 COM 初始化到執行 SQL 腳本的完整流程。
// stdafx.h
#pragma warning(disable: 4146)
#import "C:\\Program Files\\Common Files\\System\\ado\\msadox.dll" no_namespace
#import "C:\\Program Files\\Common Files\\System\\ado\\msado15.dll" no_namespace rename("EOF", "EndOfFile")
#pragma warning(default: 4146)
路徑請依實際安裝位置調整(通常在 C:\Program Files\Common Files\System\ado\)。
CoInitialize(NULL);
try {
ADOX::_CatalogPtr catalog;
catalog.CreateInstance(__uuidof(ADOX::Catalog));
CString conn = _T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\Test.mdb;");
catalog->Create(_bstr_t(conn)); // 建立空資料庫檔案
}
catch (_com_error& e) {
AfxMessageBox(_T("建立 MDB 失敗:") + e.ErrorMessage());
}
_ConnectionPtr conn;
conn.CreateInstance(__uuidof(Connection));
conn->Open(_bstr_t("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\Test.mdb;"), "", "", adConnectUnspecified);
// 執行單條 SQL
CString sql = _T("CREATE TABLE Users (ID COUNTER PRIMARY KEY, Name TEXT(50), Age INT)");
conn->Execute(_bstr_t(sql), NULL, adExecuteNoRecords);
BOOL RunSqlScript(LPCTSTR file, _ConnectionPtr& conn, CString& errLog, char sep = ';', char rem = '-')
{
CFile f; if (!f.Open(file, CFile::modeRead)) return FALSE;
UINT len = (UINT)f.GetLength();
CStringA buf; f.Read(buf.GetBuffer(len), len); buf.ReleaseBuffer(); f.Close();
CStringA sql; BOOL inRem = FALSE, skip = FALSE;
for (int i = 0; i < buf.GetLength(); ++i) {
char c = buf[i];
if (inRem) { if (c == '\n') inRem = FALSE; continue; }
if (c == rem && i+1 < buf.GetLength() && buf[i+1] == rem) { inRem = TRUE; ++i; continue; }
if (c == sep) {
if (!sql.IsEmpty() && !skip) {
try {
conn->Execute(_bstr_t(sql), NULL, adExecuteNoRecords);
errLog += _T("OK: ") + CString(sql) + _T("\r\n");
} catch (_com_error& e) {
errLog += _T("ERR: ") + CString(sql) + _T(" -> ") + e.ErrorMessage() + _T("\r\n");
return FALSE;
}
}
sql.Empty(); skip = FALSE; continue;
}
if (c == rem && i+1 < buf.GetLength() && buf[i+1] == rem) { skip = TRUE; continue; }
if (!skip) sql += c;
}
return TRUE;
}
conn->Close();
CoUninitialize();
-- 建立產品表
CREATE TABLE Products (
PID COUNTER PRIMARY KEY,
PName TEXT(100) NOT NULL,
Price CURRENCY DEFAULT 0,
Stock INT DEFAULT 0
);
-- 建立索引
CREATE INDEX IDX_PName ON Products (PName);