Delphi - MS SQL adatbázis kezelés Delphi-ből

MS SQL 31. rész

forráskód letöltése
Az SQL-DMO (Distributed Management Object) az SQL Server belső objektumainak COM reprezentációja. Része az SQL-DMF-nek, vagyis a Distributed Management Framework-nek. Az SQL-DMF olyan objektumok és szervizek gyűjteménye, amik az SQL Server működtetését és karbantartását célozzák. Az SQL-DMO tulajdonképpen egy OLE Automation Server. Hozzáférést biztosít az SQL Server adatbázis objektumaihoz (táblákhoz, tárolt eljárásokhoz, indexekhez, triggerekhez, stb.), illetve olyan metódusokat biztosít, amelyekkel végrehajthatók a szokásos SQL műveletek (feladatok ütemezése, replikációk kezelése, riasztások, stb.).
Sorozatunk mostani részében ezeket vesszük szemügyre. Az SQL-DMO egyszerűsített objektum hierarchiája a következő:
Application
	SQLServers
		SQLServer
			BackupDevices
			Logins
			Languages
			RemoteServers
			Databases
				Database
					StoredProcedures
					Rules
					Defaults
					Users
					FileGroups
					Tables
						Table
							Columns
							Indexes
							Triggers
							Keys
							Checks
					Views
Az objektumok jól szervezett és teljesen logikus, könnyen használható struktúrában állnak össze. Az SQLServer objektumnak például van egy Database kollekciója, a Database objektumnak egy Table kollekciója, a Table objektum pedig tartalmazza a triggerek, a kulcsok, a mezők kollekcióit. Így a struktúrán megfelelően lépegetve minden objektumot megtalálhatunk.
A SQL-DMO eléréséhez szükséges a Microsoft SQL Server 7 Client Tools telepítése. Ha NT Serveren dolgozunk, és az SQL Server 7 telepítve van, akkor ezzel nem kell külön foglalkoznunk. A szükséges fájlok a következők:
  • sqldmo.hlp Help file. Egész jól használható.
  • sqldmo.dll Ez az OLE szerver.
  • sqldmo.rll Resource fájl.
  • sqlresld.dll SQL Enterprise Manager Resource DLL Loader.
  • sqlsvc.dll Database Service Layer.
  • sqlsvc.dll Resource fájl.
  • sqlwoa.dll SQL Server Unicode/ANSI Translation Layer.
  • sqlwid.dll SQL Server Unicode/ANSI Translation Layer.
  • w95scm.dll SQL Service Control Manager Abstraction Layer.
  • pre60to7.sql
  • pre65to7.sql
Miután telepítettük az SQL-DMO környezetet a számítógépre, az objektumokat ugyanolyan könnyen elérhetjük, mint más OLE Automation objektumokat.

Delphi-ből legalább kétféle módon érhetjük el az OLE Automation szervereket. Az egyik megoldás szerint az IDispatch OLE osztályon keresztül szólítjuk meg a szervert.
uses
  ComObj;
var
  SQL_DMO: Variant;
begin
  SQL_DMO := CreateOLEObject('SQLDMO.SQLServer');
  ...
end;
Amikor a CreateOleObject metódust hívjuk, paraméterként a program azonosítóját kell megadni (ProgID). Ez az SQL_DMO automation szerver esetében 'SQLDMO.SQLServer'. Ezen azonosító alapján keresi ki a rendszer a registry-ből az automation szerver CLSID-jét, vagyis egyedi osztályazonosító kódját. Utána ellenőrzi, hogy a hivatkozott szerver be van-e töltve a memóriába, és ha nincs, betölti, majd megkeresi az Automation szerver interfészét. A CreateOleObject metódus visszatérési értéke erre az interfészre mutató pointer lesz. Miután visszakaptuk az interfész címét, elkezdhetjük hívogatni az Automation szerver metódusait.
Fontos, hogy hivatkozzunk a ComObj unitra, ez tartalmazza ugyanis az OLE Automation szerverek eléréséhez szükséges rutinokat. Amikor kiadjuk a CreateOLEObject utasítást, a Delphi valójában több ComObj-beli eljárást hív meg (VarDispInvoke, DispatchInvoke, GetIDsOfNames).

A másik megoldás szerint legyártjuk az OLE szerver type library-jét, uses kulcsszó után hivatkozunk rá, és használhatjuk a benne definiált valamennyi interfészt, objektumot, metódust, stb.
uses
  SQLDMO_TLB;
var
  SQL_DMO: _SQLServer;
begin
  SQL_DMO := CoSQLServer.Create;
  ...
end; 
Ehhez először elő kell állítani a type library-t. Válasszuk ki a Project menü Import Type Library pontját. A kapott dialógusablakban láthatjuk a gépünkön elérhető összes COM objektumot. Válasszuk ki a Microsoft SQLDMO Object Library (Version 7.0)-t, majd kattintsunk az OK-ra. A Delphi ekkor előállítja az SQLDMO_TLB.pas állományt és fölveszi a projectbe. Érdemes tanulmányozni, mert nagyon könnyen érthető, és a help fájl mellett az egyetlen forrásunk, amiből kiderül, hogy milyen metódusokat is hívhatunk.

Ennek az eljárásnak az előnye, hogy a Delphi a unit segítségével típusellenőrzést tud végrehajtani, működni fog a code completion funkció és sokkal gyorsabb is, mert egy hatékonyabb módszerrel történik a COM objektumok megszólítása. Ezzel szemben az IDispatch interfész használata csak annyi előnyt jelent, hogy Variant típusokat használhatunk, és így egy kicsit 'lazábban' programozhatunk.

A példaprogramban az IDispatch interfészt használjuk. Rácsatlakozunk a lokális SQL Serverre, kilistázzuk annak összes adatbázisát, majd egy tetszőleges adatbázis tábláit, végül egy tábla mezőit.

A csatlakozás egyszerűen megy. Miután létrehoztuk az SQL_DMO nevű interfészt, beállítunk egy-két paramétert, majd meghívjuk a Connect metódust. Ha beletúrunk a type library-be, rábukkanunk az
_SQLServer = interface
sorra, és alatta találjuk az interfészen keresztül elérhető objektum metódusait és property-jeit. Hogy ne legyen olyan egyszerű az életünk, az IDispatch interfészen keresztül nem látunk rá az egész objektumra. Hogy mit használhatunk, azt az
_SQLServerDisp = dispinterface
sor utáni listából tudjuk meg. A type library-ben egy interface után mindig ott találjuk a dispinterface definícióját is.

A Connect metódus paraméterezése a következő:
Connect(ServerName, Login, Password)
Az első paraméter az SQL szerver neve, a login a bejelentkező név a password pedig a jelszó. Mindhárom paraméter opcionális. Ha nem adunk meg szervernevet, akkor a helyi SQL Server-hez csatlakozunk, ha ilyen nincs, akkor az alkalmazásunkat futtató számítógép hálózati nevével egyező nevű SQL Servert keresünk. Ha SQL Server autentikációt használunk, akkor meg kell adnunk a bejelentkező nevet és a jelszót is, ha Windows NT autentikációt, akkor ezt nem kell megadnunk, de a LoginSecure property-t true-ra kell állítanunk. A LoginTimeout és az AutoReconnect property-k önmagukért beszélnek. Az ApplicationName property beállításával tudatjuk az SQL Serverrel, hogy éppen ki veszi az erőforrásait igénybe. Erre akkor lehet szükség, ha egy monitorprogrammal (pl. SQL Server Profiler) vizsgáljuk a szerverünket, mert jól el tudjuk különíteni az egyes alkalmazások erőforrásigényét. (Megjegyzés: ha nem az IDispatch utat járjuk, a Connect paramétereit korrekt módon meg kell adnunk a típusellenőrzés miatt.)
  SQL_DMO := CreateOLEObject('SQLDMO.SQLServer');
  SQL_DMO.LoginSecure := true;
  SQL_DMO.LoginTimeout := 30;
  SQL_DMO.AutoReconnect := true;
  SQL_DMO.ApplicationName := 'SQL_DMO Test Program';
  SQL_DMO.Connect('.');
Ellenőrizzük le, hogy felépült-e a kapcsolat: Erre a VerifyConnection metódust használhatjuk, és paraméterként megadhatjuk, hogy sikertelen kísérlet esetén mi történjen. Az SQLDMOConn_ReconnectIfDead érték azt jelenti, hogy sikertelen kapcsolatfelvétel esetén az alkalmazás újra próbálkozik.
  if not SQL_DMO.VerifyConnection(SQLDMOConn_ReconnectIfDead)
    then raise Exception.Create('Hiba a csatlakozáskor.')
Sikeres csatlakozás után szemügyre vehetjük a type library többi objektumát is. A Databases objektum tartalmazza a szerver adatbázisait. A Count property az adatbázisok számát, az Items tömb magukat az adatbázisokat mutatja. Arra oda kell figyelni, hogy minden kollekcióban az első elem az 1 sorszámot kapja és nem a 0-t. Tehát végigmegyünk a Databases kollekción, és minden adatbázis nevét egy listbox-ba írjuk.
  for i := 1 to SQL_DMO.Databases.Count do
    lbDatabases.Items.Add(SQL_DMO.Databases.Item(i, null).name);
Az adatbázis tábláit (ami szintén egy kollekció), így érhetjük el:
SQL_DMO.Databases.Item(_adatbázis_sorszám_, null).Tables
A Tables objektumnak szintén van Count és Items property-je, így a táblák leválogatása az adatbázisokéhoz hasonlóan egyszerű:
  SQL_DB := SQL_DMO.Databases.Item(lbDatabases.ItemIndex+1, null);
  for i := 1 to SQL_DB.Tables.Count do
    if not SQL_DB.Tables.Item(i, null).SystemObject then
      lbTables.Items.Add(SQL_DB.Tables.Item(i, null).name);
A feltételre azért van szükség, mert a rendszertáblákra nem vagyunk kíváncsiak.
Végül egy tábla mezőinek nevét így kapjuk:
  SQL_OBJ := SQL_DB.Tables.Item(_tábla_sorszám_, null);
  for i := 1 to SQL_OBJ.Columns.Count do
    lbFields.Items.Add(SQL_OBJ.Columns.item(i).Name);


MS SQL cikksorozat

MS SQL adatbázis kezelés Delphi-ből - 1. rész
MS SQL adatbázis kezelés Delphi-ből - 2. rész
MS SQL adatbázis kezelés Delphi-ből - 3. rész
MS SQL adatbázis kezelés Delphi-ből - 4. rész
MS SQL adatbázis kezelés Delphi-ből - 5. rész
MS SQL adatbázis kezelés Delphi-ből - 6. rész
MS SQL adatbázis kezelés Delphi-ből - 7. rész
MS SQL adatbázis kezelés Delphi-ből - 8. rész
MS SQL adatbázis kezelés Delphi-ből - 9. rész
MS SQL adatbázis kezelés Delphi-ből - 10. rész
MS SQL adatbázis kezelés Delphi-ből - 11. rész
MS SQL adatbázis kezelés Delphi-ből - 12. rész
MS SQL adatbázis kezelés Delphi-ből - 13. rész
MS SQL adatbázis kezelés Delphi-ből - 14. rész
MS SQL adatbázis kezelés Delphi-ből - 15. rész
MS SQL adatbázis kezelés Delphi-ből - 16. rész
MS SQL adatbázis kezelés Delphi-ből - 17. rész
MS SQL adatbázis kezelés Delphi-ből - 18. rész
MS SQL adatbázis kezelés Delphi-ből - 19. rész
MS SQL adatbázis kezelés Delphi-ből - 20. rész
MS SQL adatbázis kezelés Delphi-ből - 21. rész
MS SQL adatbázis kezelés Delphi-ből - 22. rész
MS SQL adatbázis kezelés Delphi-ből - 23. rész
MS SQL adatbázis kezelés Delphi-ből - 24. rész
MS SQL adatbázis kezelés Delphi-ből - 25. rész
MS SQL adatbázis kezelés Delphi-ből - 26. rész
MS SQL adatbázis kezelés Delphi-ből - MS SQL 27. rész
MS SQL adatbázis kezelés Delphi-ből - MS SQL 28. rész
MS SQL adatbázis kezelés Delphi-ből - MS SQL 29. rész
MS SQL adatbázis kezelés Delphi-ből - MS SQL 30. rész

MS SQL adatbázis kezelés Delphi-ből - MS SQL 31. rész

MS SQL adatbázis kezelés Delphi-ből - MS SQL 32. rész