Komunikacja z bazami danych ActiveX Data Objects (ADO)

advertisement
Komunikacja z bazami danych
ActiveX Data Objects (ADO)
dr Zbigniew Lipiński
Instytut Matematyki i Informatyki
ul. Oleska 48
50-204 Opole
[email protected]
Co to jest ActiveX Data Objects?
ADO jest
•
technologią firmy Microsoft.
•
komponentem Active-X (ACTIVE eXchange).
•
automatycznie instalowany z serwerem WWW Microsoft IIS.
•
interfejsem programowym dostępu do baz danych.
Kontrolka Active-X - wcześniejsza nazwa kontrolką OLE, jest przykładem obiektu typu COM. Komponent
realizujący określoną funkcjonalność, który może być zagnieżdżany w aplikacje, okna dialogowe, strony HTML.
Kontrolka Active-X to plik z rozszerzeniem *.ocx
Obiekty ADO:
ADO Command
ADO Connection
ADO Error
ADO Field
ADO Parameter
ADO Property
ADO Record
ADO Recordset
ADO Stream
ADO DataTypes
2
Obiekty ADO
Obiekt Command – stosowany do wykonania kwerend do bazy danych w celu utworzenia, uaktualnienia, dodania,
pobrania, usunięcia (create, add, retrieve, delete, update) rekordu.
Jeżeli kwerenda służyła do pobrania danych, to dane są zwracane jako obiekt RecordSet (zbiór rekordów).
Aby odzyskać dane z obiektu RecordSet należy posłużyć się metodami, properties, collections, obiektu Recordset.
Tworzenie obiektu w asp .Net
set objCommand=Server.CreateObject("ADODB.command")
Obiekt Connection –obiekt służy do budowy i otwarcia połączenia z bazą danych.
Tworzenie obiektu w asp .Net
set objConnection=Server.CreateObject("ADODB.connection")
3
Obiekty ADO
Obiekt Error - obiekt zawiera dane o błędach powstałych przy wykonaniu pojedynczych operacji na bazie danych.
Przykład użycia.
for each objErr in objConn.Errors
response.write(objErr.Description )
response.write(objErr.HelpContext)
response.write(objErr.HelpFile)
response.write(objErr.NativeError)
response.write(objErr.Number)
response.write(objErr.Source)
response.write(objErr.SQLState)
Next
Obiekt Field – obiekt przechowuje informacje o kolumnie danych w obiekcie Recordset.
Tworzenie obiektu w asp .Net
set objField=Server.CreateObject("ADODB.field")
4
Obiekty ADO
Obiekt Parameter – obiekt służy do uzyskania informacji o parametrach użytych w procedurach składowanych (stored
procedures) lub kwerendach.
Cztery typy parametrów: input, output, input/output, return.
Przykład składni.
objectname.property
objectname.method
Obiekt Property - obiekt reprezentuje dynamiczne charakterystyki obiektów ADO zdefiniowanych dla różnych
typów baz danych (db providers).
Tworzenie obiektu w asp .Net
set objProperty=Server.CreateObject("ADODB.property")
5
Obiekty ADO
Obiekt Record (ADO ver. 2.5) – obiekt służy do przechowania wiersza danych z Recordsetu, katalogu lub pliku.
Przykład użycia:
objectname.property
objectname.method
Obiekt Recordset - obiekt służy do przechowywania danych (zbioru rekordów) z tabeli. Obiekt Recordset składa się z
rekordów i kolumn (pól, ang. Fields).
Recordset może uaktualnić dane na dwa sposoby: immediate updating, batch updating.
Tworzenie obiektu w asp .Net
set objRecordset=Server.CreateObject("ADODB.recordset")
Obiekt Stream (ADO version 2.5) – obiekt stosowany do czytania, zapisywania, zarządzania strumieniem danych.
6
Kursory ADO
Kursory ADO są parametrami metod obiektów ADO.
Kursory definiują usługi kursora (cursor service).
Typy kursorów ADO:
Dynamic cursor – pozwala na przegląd operacji dodania, zmiany, usunięcia wykonane przez innego użytkownika.
Keyset cursor – usługa podobna do usługi kursora ‘dynamic’, za wyjątkiem
- braku możliwości przeglądania operacji dodania przez innego użytkownika,
- braku dostępu do rekordów które inny użytkownik usunął.
Dane zmienione (update) przez innego użytkownika są widoczne.
Static cursor – pozwala dokonać ‘statycznego’ kopiowania rekordsetów w celu znalezienia danych lub
wygenerowania raportów. Operacje dodania, zmiany, usunięcia wykonane przez innego użytkownika są niewidoczne.
Typ kursora dostępny tylko dla obiektów typu klient rekordset.
Forward-only cursor – pozwala przejrzeć rekordset. Operacje dodania, zmiany, usunięcia wykonane przez innego
użytkownika są niewidoczne.
Kursor Forward-only może być ustawiony poprzez property ‘CursorType’ lub poprzez parametr ‘CursorType’ w
metodzie Open().
7
Budowa połączenia z bazą danych
Proces budowy połączenia z bazą danych za pomocą obiektów ADO:
1.
Utworzenie połączenia ADO z bazą danych.
2.
Otwarcie połączenia.
3.
Utworzenie recordseta.
4.
Otwarcie recordseta.
5.
Pobranie danych do recordseta.
6.
Zamknięcie recordseta.
7.
Zamknięcie połączenia.
8
Połączenie z bazą danych za pomocą serwera WWW
1-2. Utworzenie i otwarcie połączenia z bazą danych. Baza northwind.mdb., Northwind_en 2007.accdb,
northwind_pl 2007.accdb, northwind.accdb.
set conn = Server.CreateObject("ADODB.Connection")
conn.Provider="Microsoft.Jet.OLEDB.4.0"
conn.Open "c:/webdata/northwind.mdb”
Utworzenie i otwarcie połączenia z bazą danych za pomocą komponentu ODBC (Open DataBase Connectivity).
set conn = Server.CreateObject("ADODB.Connection")
conn.Open "northwind"
3. Utworzenie recordseta.
set rs = Server.CreateObject("ADODB.recordset")
9
Połączenie z bazą danych za pomocą serwera WWW
4-5. Otwarcie i pobranie danych do recordseta.
Czytanie danych z rekordseta.
rs.Open "Select * from Customers", conn
for each x in rs.fields
response.write(x.name)
response.write(" = ")
response.write(x.value)
Next
6. Zamknięcie recordseta.
rs.close
7. Zamknięcie połączenia.
conn.close
10
Metody dostępu do bazy danych
Tabular Data Stream (TDS) dla SOAP
Metody dostępu do bazy danych. Źródło biblioteka MSDN.
11
Połączenie z bazą danych Microsoft Access
Silniki dla baz danych MS Access:
•
Microsoft JET engine (Joint Engine Technology, 1992),
•
ACE Engine (Microsoft Access Engine, 2007).
Cechy ACE Engine:
•
nowy format danych .accdb,
•
dodano obsługę złożonych typów danych,
•
nowe mechanizmy szyfrowania,
•
możliwość integracji z Windows SharePoint Services 3.0, Microsoft Office Outlook 2007.
Typy dostępu do danych Microsoft Access:
•
ADO (ActiveX Data Objects),
•
ATL OLE DB (Active Template Library Object Linking and Embedding DB),
•
Direct DAO (Data Access Objects),
•
ODBC (Open Database Connectivity),
•
MFC ODBC (Microsoft Foundation Classes Open Database Connectivity).
12
Połączenie z bazą danych Microsoft Access za pomocą obiektów ADO
Funkcje biblioteki COM.
Funkcja : CoInitialize().
HRESULT CoInitialize( _In_opt_ LPVOID pvReserved);
Argumenty: pvReserved [in, optional] - parametr zarezerwowany, musi być NULL.
Zwracana wartość:
S_OK
- biblioteka COM zainicjowana.
S_FALSE
- biblioteka COM jest już zainicjowana.
RPC_E_CHANGED_MODE - inicjowany proces wielowątkowy multithread apartment (MTA).
Opis:
Funkcja inicjuje bibliotekę obiektów COM, zwraca wskaźnik do pamięci COM i funkcji COM.
13
Połączenie z bazą danych Microsoft Access - ADO
Funkcje biblioteki COM.
Funkcja: CoUninitialize().
void CoUninitialize(void);
Argumenty: brak
Zwracana wartość: void
Opis: Funkcja zamyka bibliotekę obiektów COM.
Funkcje Windows: GetCount(), GetItem(), GetName(), GetValue().
Funkcje służą do manipulacji złożonymi typami danych.
Property (język CLI C++):
Description – zwraca opis błędu.
get_Fields – zwraca informacje o konfiguracji zasobów.
Klasy i struktury:
_bstr_t , _variant_t - klasy służące do zarządzania zasobami przy wywoływaniu funkcji.
14
Struktura programu - połączenie z bazą danych Microsoft Access - ADO
Konfiguracja projektu.
Kompilator: MS Visual Studio 2008
Projekt:
Visual C++, Win32, Win32 Console application, Console application, empty project.
Baza danych:
Northwind_pl 2007.accdb
Northwind_uk 2007.accdb
#import <C:\\Program Files\\Common Files\\System\\ado\\msado15.dll>
\
rename( "EOF", "AdoNSEOF" )
#include <iostream>
#include <tchar.h>
using namespace std;
// string identyfikujący bazę danych
_bstr_t bstrConnect =
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Northwind 2007.accdb;";
15
Struktura programu - połączenie z bazą danych Microsoft Access - ADO
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = CoInitialize(NULL);
// inicjowanie obiektu COM
if (FAILED(hr))
{
cout << "Błąd wywołania funkcji CoInitialize()" << endl;
return hr;
}
try
// obsługa błędów COM w bloku try catch
{
ADODB::_ConnectionPtr pConn("ADODB.Connection");
hr = pConn->Open(bstrConnect, "admin", "", ADODB::adConnectUnspecified);
if (SUCCEEDED(hr))
{
cout<<"Połącznie z bazą: \n " << pConn->GetConnectionString() << endl;
_bstr_t query = // kwerenda SQL
"SELECT Customers.[Company], Customers.[First Name] FROM Customers;";
// cout << "SQL query:\n
" << query << endl;
// wysłanie kwerendy, utworzenie record set’a
ADODB::_RecordsetPtr pRS("ADODB.Recordset");
hr = pRS->Open(query,
_variant_t((IDispatch *) pConn, true), //cast Idispatch, ADO jest interf. typu
ADODB::adOpenUnspecified,
// Idispatch dziedziczy od interfesju IUnknown
ADODB::adLockUnspecified,
ADODB::adCmdText);
16
Struktura programu - połączenie z bazą danych Microsoft Access - ADO
if (SUCCEEDED(hr))
{
cout << "Informacja o strukturze: " << endl;
ADODB::Fields* pFields = NULL;
hr = pRS->get_Fields(&pFields);
if (SUCCEEDED(hr) && pFields && pFields->GetCount() > 0)
{
for (long nIndex=0; nIndex < pFields->GetCount(); nIndex++)
{
cout<<" | "<<_bstr_t(pFields->GetItem(nIndex)->GetName());
}
cout << endl;
}
else
{
cout << "Błąd, liczba pól ma wartość zero." << endl;
}
cout << "Pobieranie danych: " << endl;
int rowCount = 0;
while (!pRS->AdoNSEOF)
{
for (long nIndex=0; nIndex < pFields->GetCount(); nIndex++)
{
cout<<" | "<<_bstr_t(pFields->GetItem(nIndex)->GetValue());
}
cout << endl;
pRS->MoveNext();
rowCount++;
}
cout << "Liczba pobranych wierszy: " << rowCount << endl;
}
pRS->Close();
pConn->Close();
cout << "Połączenie zamknięte" << endl;
}
17
Struktura programu - połączenie z bazą danych Microsoft Access - ADO
else
{
cout << "Błąd połączenia z bazą: " << bstrConnect << endl;
}
}
catch(_com_error& e)
{
cout << "Błąd COM: " << e.Description() << endl;
}
CoUninitialize();
// zwolnienie biblioteki COM
return hr;
}
18
Połączenie z bazą danych metodą ATL OLE DB
Konfiguracja projektu.
Kompilator: MS Visual Studio 2008
Projekt:
Visual C++, Win32, Win32 Console application, Console application + ATL lub empty project.
Baza danych:
Northwind_pl 2007.accdb
Northwind_uk 2007.accdb
Parametry projektu: Character Set: Use Multi-Byte Character Set.
Active Template Library (ATL) – biblioteka szablonów klas C++ do tworzenie obiektów COM.
CDataSource - klasa, reprezentuje typ danych OLE DB.
CSession
- klasa, reprezentuje typ danych służący do dostępu do danych w pojedynczej sesji.
CComVariant - klasa ATL, typ zawierający typy przechowywanych danych.
Metody biblioteki ATL:
GetInitializationString() - metoda klasy CDataSource pobiera dane inicjujące z otwartego źródła danych.
OpenFromInitializationString() – metoda otwiera źródło danych zidentyfikowane przez dane inicjujące.
OLE2T(), COLE2T() – makra konwertujące stringi ATL.
Funkcje Windows: GetColumnCount(), GetColumnInfo().
19
Struktura programu - połączenie z bazą danych metodą ATL OLE DB
#include <atldbcli.h>
#include <atldbsch.h>
#include <iostream>
using namespace std;
// string identyfikujący bazę danych
LPCOLESTR lpcOleConnect =
L"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Northwind 2007.accdb; User Id=admin; Password=;";
20
Struktura programu - połączenie z bazą danych metodą ATL OLE DB
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = CoInitialize(NULL); // inicjowanie obiektu COM
if (FAILED(hr))
{
cout <<"Błąd wywołania funkcji CoInitialize()" << endl;
return hr;
}
// deklaracja obiektów klas CDataSource and CSession z biblioteki ATL
CDataSource dbDataSource;
CSession dbSession;
// użycie makra ATL konwertującego stronę kodową
USES_CONVERSION;
// otwarcie połączenia
hr = dbDataSource.OpenFromInitializationString(lpcOleConnect);
if (FAILED(hr))
{
cout<<" Błąd połączenia z bazą " << OLE2T(lpcOleConnect)<<endl;
}
else
{
hr = dbSession.Open(dbDataSource);
if (FAILED(hr))
{
cout<<" Błąd, budowy sesji z bazą "<< OLE2T(lpcOleConnect)<<endl;
}
else
{
CComVariant var;
hr = dbDataSource.GetProperty(DBPROPSET_DATASOURCEINFO, DBPROP_DATASOURCENAME, &var);
if (FAILED(hr) || (var.vt == VT_EMPTY))
{
cout <<"Niewłaściwa nazwa bazy " << endl;
}
21
Struktura programu - połączenie z bazą danych metodą ATL OLE DB
else
{
cout<<"Połączenie z bazą:\n
" << COLE2T(var.bstrVal)<<endl;
// kwerenda SQL
LPCOLESTR query = L"SELECT Customers.[Company], Customers.[First Name] FROM Customers;";
// cout<<"Kwarenda SQL:\n " << OLE2T(query)<<endl;
// Wysłanie kwarendy, utworzenie record set’a
CCommand<CDynamicStringAccessor> cmd;
hr = cmd.Open(dbSession, query);
DBORDINAL colCount = cmd.GetColumnCount();
if (SUCCEEDED(hr) && 0 < colCount)
{
cout<<" Pobranie informacji o strukturze danych "<<endl;
DBORDINAL cColumns;
DBCOLUMNINFO* rgInfo = NULL;
OLECHAR* pStringsBuffer = NULL;
cmd.GetColumnInfo(&cColumns, &rgInfo, &pStringsBuffer);
for (int col=0; col < (int)colCount; col++)
{
cout<<" | "<<OLE2T(rgInfo[col].pwszName);
}
cout<<endl;
22
Struktura programu - połączenie z bazą danych metodą ATL OLE DB
cout<<"Pobranie danych: "<<endl;
int rowCount = 0;
CRowset<CDynamicStringAccessor>* pRS =(CRowset<CDynamicStringAccessor>*)&cmd;
// Pobranie wierszy z danymi
while (pRS->MoveNext() == S_OK)
{
for (int col=1; col <= (int)colCount; col++)
{
CHAR* szValue = cmd.GetString(col);
cout<<" | "<<szValue;
}
cout<<endl;
rowCount++;
}
cout<<" Liczba wierszy: " << rowCount<<endl;
}
else
{
cout<<"Błąd, liczba pól zero."<<endl;
}
}
}
}
dbDataSource.Close();
dbSession.Close();
CoUninitialize();
return hr;
}
23
Połączenie z bazą danych metodą Direct ODBC
Konfiguracja projektu.
Kompilator: MS Visual Studio 2008
Projekt:
Visual C++, Win32, Win32 Console application, Console application, empty project.
Baza danych:
Northwind_pl 2007.accdb
Northwind_uk 2007.accdb
Parametry projektu: Character Set: Use Multi-Byte Character Set
Funkcje biblioteki ODBC:
SQLAllocEnv() , SQLAllocConnect(), SQLAllocStmt() -funkcje alokują uchwyty do zmiennych
środowiskowych, połączenia, wyrażeń.
SQLDriverConnect() – funkcaj buduje połączenie, zwracając ‘string połączenia’.
SQL_SUCCEEDED()
SQLPrepare()
SQLBindCol()
SQLExecute()
SQLNumResultCols()
SQLDescribeCol)
SQLFetch()
SQLFreeStmt(), SQLFreeHandle() – funkcje zwalniają uchwyty.
24
Struktura programu - połączenie z bazą danych metodą Direct ODBC
#include <windows.h>
#include <stdio.h>
#include <sqlext.h>
// string identyfikujący bazę danych w ODBC
char szDSN[256] =
"Driver={Microsoft Access Driver (*.mdb, *.accdb)}; DSN=''; DBQ=C:\\Northwind 2007.accdb;";
25
Struktura programu - połączenie z bazą danych metodą Direct ODBC
main()
{
HENV
hEnv;
HDBC
hDbc;
RETCODE rc;
// property, uchwyt do zmiennej środowiskowej
// property, uchwyt do połączenia odbc
// ODBC API return status
int
iConnStrLength2Ptr;
char
szConnStrOut[256];
unsigned char* query = "SELECT Customers.[Company], Customers.[First Name] FROM Customers;";
SQLCHAR
chval1[128], chval2[128], colName[128];
int
ret1;
int
ret2;
// Number of rows and columns in result set
SQLINTEGER
rowCount = 0;
SQLSMALLINT
fieldCount = 0, currentField = 0;
HSTMT
hStmt; //property, uchwyt do wyrażeń odbc
rc = SQLAllocEnv(&hEnv);
rc = SQLAllocConnect(hEnv, &hDbc);
// alokacja zmiennej środowiskowej hEnv
// alokacja uchwytu do połączenia hDbc
// Połączenie z bazą
rc = SQLDriverConnect(hDbc, NULL, (unsigned char*)szDSN,
SQL_NTS, (unsigned char*)szConnStrOut,
255, (SQLSMALLINT*)&iConnStrLength2Ptr, SQL_DRIVER_NOPROMPT);
if (SQL_SUCCEEDED(rc))
{
printf("Połączenie z bazą: \n %s \n", szConnStrOut);
// printf("SQL query:\n %s\n", query); // Kwerenda SQL
rc = SQLAllocStmt(hDbc,&hStmt);
rc = SQLPrepare(hStmt, query, SQL_NTS);
// Połączenie (bind) danych pobranych z bazy z buforem
rc = SQLBindCol(hStmt, 1, SQL_C_CHAR, chval1, 128, (SQLINTEGER*)&ret1);
rc = SQLBindCol(hStmt, 2, SQL_C_CHAR, chval2, 128, (SQLINTEGER*)&ret2);
26
Struktura programu - połączenie z bazą danych metodą Direct ODBC
// wykonanie kwerendy i utworzenie recordset’a
rc = SQLExecute(hStmt);
if (SQL_SUCCEEDED(rc))
{
printf("Pobranie informacji o strutkurze danych:\n");
SQLNumResultCols(hStmt, &fieldCount);
if (fieldCount > 0)
{
for (currentField=1; currentField <= fieldCount; currentField++)
{
SQLDescribeCol(hStmt, currentField,
colName, sizeof(colName), 0, 0, 0, 0, 0);
printf(" | %s", colName);
}
printf("\n");
}
else
{
printf("Błąd, liczba pól zero. \n");
}
printf("Pobranie danych.\n");
rc = SQLFetch(hStmt);
while (SQL_SUCCEEDED(rc))
{
printf(" | %s | %s\n", chval1, chval2);
rc = SQLFetch(hStmt);
rowCount++;
};
printf("Liczba wierszy: %d\n", rowCount);
rc = SQLFreeStmt(hStmt, SQL_DROP);
}
}
else
{
printf("Brak połaczenia z %s.\n", szDSN);
// rozłączenie, zwolnienie uchwytów
SQLDisconnect(hDbc);
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
}
}
27
Download