Adatbázis rendszerek II. Adatbázis elérése C# kliens programból ADO.NET API-n keresztül Adatbázis elérés lehetőségei absztrakciós rétegen keresztül: - Open DataBase Connectivity (ODBC), közös függvényhalmaz, amivel minden DB elérhető. Az ODBC rétegben lévő driverek lefordítják. - Object Linking and Embedding (OLE DB): táblázatos formában mutatja az adatokat. Az adatforrások OLE DB provider-eken keresztül érhetők el COM objektumok segítségével. ODBC-t is elér. - ActiveX Data Objects (ADO): egy vékony réteg az OLE DB felett, a magas szintű nyelvek számára elérhetővé teszi azt. - ADO.NET: ADO továbbfejlesztett, felügyelt változata. ADO.NET: ADO továbbfejlesztett, felügyelt változata. A.NET adatbáziskezelési osztálygyűjteménye. Névtér: System.Data Data provider (adatszolgáltató): híd az alkalmazás és az adatforrás között. Ezen keresztül mozognak az adatok az alkalmazás és az adatbázis között. Microsoft adatszolgáltatók: SqlClient (MS SQL Server), OracleClient (Oracle), OleDb (Access), Odbc. Oracle Data Provider for.net: http://www.oracle.com/technetwork/topics/dotnet/downloads/index.html Kapcsolat alapú adatelérés: Adatbázis-kezelés lépései kliens programból: 1. Adatbázis kapcsolat létesítése ConnectionString: a kapcsolat beállításai (szerver, felhasználónév, jelszó) Connection objektum: ezen keresztül kommunikál az alkalmazás az adatbázissal OracleConnection: Oracle adatbázis eléréshez használható Connection típus 2. Adatbázis műveletek végrehajtása Command objektum: ezen keresztül adhatók meg a végrehajtandó SQL parancsok OracleCommand: Command típus, Oracle adatbáziskezelés esetén használható osztály Parameters tulajdonság: az SQL parancsok vagy tárolt eljárások bemenő és kimenő paraméterei ExecuteReader metódus: SQL lekérdezés végrehajtása ExecuteNonQuery metódus: SQL írási művelet végrehajtása DataReader objektum: lekérdező művelet esetén az adatbázisból visszakapott eredmény rekord adatfolyam. Gyors elérésű, csak előre irányban feldolgozható szerver oldali kurzor. Az aktuális sor egyes oszlopaiban tárolt adatokat a típusuk szerinti Get metódusokkal lehet lekérdezni. 3. Adatbázis kapcsolat lezárása
Oracle adatbázis kezeléshez a Data Provider letöltése és telepítése után hozzá kell adni a C# projektünkhöz a System.Data.OracleClient DLL-t. Ehhez a Projekt/Hivatkozás hozzáadása (Project/Add reference) menüpontban a.net szerelvény böngésző (.NET Assembly Browser) fül alatt tallózni kell a DLL le-t és hozzáadni. Ezután elérhető a DLL file tartalma. Érdemes using segítségével hozzáadni a DLL névterét, majd az egyes statikus metódusokra az osztálynév segítségével hivatkozhatunk. Windows Forms alkalmazás (Visual Studio 2008) példa: https://docs.oracle.com/cd/b28359_01/appdev.111/b28844/connecting.htm#tdpng30000 Adatbázis kapcsolat létesítés: using System; using System.Data.OracleClient; namespace Abkezel_demo class OraTest private OracleConnection con; Console Application feladatsor (Visual Studio 2015) void Connect() con = new OracleConnection(); con.connectionstring = "User Id=...; Password=...; Data Source = 193.6.5.58"; con.open(); Console.WriteLine("Connected to Oracle" + con.serverversion); Adatbázis kapcsolat bontás: void Close() con.close(); con.dispose(); Console.WriteLine("Sikeres kapcsolatbontás");
Adatbázis-kezelő műveletek: I. Paraméter nélküli utasítások I/1 Tábla létrehozása void CreateTable() command.commandtext = "CREATE TABLE auto_c# (rsz char(6) " + "primary key, tipus char(10) not null, szin char(10) default 'piros', " + "evjarat number(4), ar number(8) check (ar>0) )"; Console.WriteLine("Sikeres auto_c# tábla létrehozás"); I/2 Adatok feltöltése void InsertData() command.commandtext = "INSERT INTO auto_c# VALUES ('abc123', " + " 'mazda', 'fekete', 2012, 1650000)"; Console.WriteLine("Sikeres adatfelvitel"); string[ ] sql_stmts = new string[3] "INSERT INTO auto_c# VALUES('aaa111','opel','fekete',2014,1850000)", "INSERT INTO auto_c# VALUES('aaa222','skoda',null,2014,1850000)", "INSERT INTO auto_c# (rsz, tipus, evjarat, ar) VALUES ('aaa333','mazda',2014,1850000)" ; for (int i=0; i<sql_stmts.length; i++) command.commandtext = sql_stmts[i]; Console.WriteLine("Sikeres adatfelvitel");
I/3 Adatok lekérdezése void SelectData() command.commandtext = "SELECT * FROM auto_c#"; OracleDataReader reader = command.executereader(); if (reader.hasrows) while (reader.read()) OracleString rsz = reader.getoraclestring(0); Console.Write(rsz.ToString() + " "); OracleString tipus = reader.getoraclestring(1); Console.Write(tipus.ToString() + " "); OracleString szin = reader.getoraclestring(2); Console.Write(szin.ToString() + " "); OracleNumber evjarat = reader.getoraclenumber(3); Console.Write(evjarat.ToString() + " "); OracleNumber ar = reader.getoraclenumber(4); Console.WriteLine(ar.ToString() + " "); //Dátum típusú mező esetén //OracleDateTime d = reader.getoracledatetime(mezőindex); //Console.WriteLine(d.ToString()); else Console.WriteLine("No rows found"); reader.close();
II. Paraméteres utasítások, ahol a paraméterek kötött változók. II/1 Paraméteres adatfelvitel void ParametrizedInsert() string cmdtext = "INSERT INTO auto_c# VALUES (:rsz, :tipus, :szin, :evjarat, :ar)"; OracleCommand command = new OracleCommand(cmdText, con); Console.WriteLine("Paraméteres adatfelvitel"); Console.Write("Rendszám: "); string c_rsz = Console.ReadLine(); Console.Write("Típus: "); string c_tipus = Console.ReadLine(); Console.Write("Szín: "); string c_szin = Console.ReadLine(); Console.Write("Évjárat: "); string c_evjarat = Console.ReadLine(); Console.Write("Ár: "); string c_ar = Console.ReadLine(); /* Paraméterek és változók kötése */ command.parameters.add(new OracleParameter("rsz", c_rsz)); command.parameters.add(new OracleParameter("tipus", c_tipus)); command.parameters.add(new OracleParameter("szin", c_szin)); command.parameters.add(new OracleParameter("evjarat", c_evjarat)); command.parameters.add(new OracleParameter("ar", c_ar)); // Ha a nem string típusú adatok típusát konvertáljuk /* int c_evjarat = Int16.Parse(Console.ReadLine()); double c_ar = double.parse(console.readline()); command.parameters.add("evjarat", OracleType.Int16); command.parameters["evjarat"].value = c_evjarat; command.parameters.add("ar", OracleType.Double); command.parameters["ar"].value = c_ar; */ Console.WriteLine("Sikeres paraméteres adatfelvitel"); catch(exception ex) II/2 Paraméteres lekérdezés void ParametrizedQuery() string cmdtext = "SELECT * FROM auto_c# where trim(tipus) = :c_tip and ar > :c_ar"; OracleCommand command = new OracleCommand(cmdText, con); //co command.parameters.add(new OracleParameter("c_tip", "mazda")); //command.parameters.addwithvalue("c_tip", "mazda"); //típusprobléma lehet! //command.parameters.add("c_tip", OracleType.VarChar); //command.parameters["c_tip"].value = "mazda";
//command.parameters.add(new OracleParameter("c_ar", "1800000")); //command.parameters.addwithvalue("c_ar", "1800000"); command.parameters.add("c_ar", OracleType.Double); command.parameters["c_ar"].value = 1800000; OracleDataReader reader = command.executereader(); if (reader.hasrows) while (reader.read()) OracleString rsz = reader.getoraclestring(0); Console.Write(rsz.ToString() + " "); OracleString tipus = reader.getoraclestring(1); Console.Write(tipus.ToString() + " "); OracleString szin = reader.getoraclestring(2); Console.Write(szin.ToString() + " "); OracleNumber evjarat = reader.getoraclenumber(3); Console.Write(evjarat.ToString() + " "); OracleNumber ar = reader.getoraclenumber(4); Console.WriteLine(ar.ToString() + " "); else Console.WriteLine("No rows found"); reader.close(); II/3 IN paraméteres tárolt eljárás hívás void InProcedureCall() //Megadott életkornál idősebb autók árának csökkentése command.commandtext = "create or replace procedure C#_arcsokkent " + "(kor in number) is " + "begin " + "update auto_c# set ar=ar*0.9 where " + "to_char(sysdate, 'yyyy')-evjarat > kor; " + "end;"; Console.WriteLine("Tárolt eljárás létrejött"); command = new OracleCommand("C#_arcsokkent", con); command.commandtype = System.Data.CommandType.StoredProcedure; //Sample of how to bind parameters to the Stored Procedure OracleParameter korin = new OracleParameter(); korin.value = 5; //5 évnél idősebb autók árának 10%-os csökkentése
korin.parametername = "kor"; command.parameters.add(korin); korin.direction = System.Data.ParameterDirection.Input; //Execute stored procedure call Console.WriteLine("Sikeres tárolt eljárás hívás"); II/4 OUT paraméteres tárolt eljárás hívás void OutProcedureCall() //Megadott színű autók átlagárának lekérdezése command.commandtext = "create or replace procedure C#_atlagar " + "(sz in char, atl out number) is " + "begin " + "select avg(ar) into atl from auto_c# where trim(szin) = sz; " + "end;"; Console.WriteLine("Tárolt eljárás létrejött"); command = new OracleCommand("C#_atlagar", con); command.commandtype = System.Data.CommandType.StoredProcedure; //Sample of how to bind parameters to the Stored Procedure OracleParameter szinin = new OracleParameter("sz", OracleType.VarChar); Console.Write("Milyen színű autók átlagárát kérdezed? "); szinin.value = Console.ReadLine(); szinin.direction = System.Data.ParameterDirection.Input; command.parameters.add(szinin); OracleParameter atlout = new OracleParameter("atl",OracleType.Number); atlout.direction = System.Data.ParameterDirection.Output; command.parameters.add(atlout); //Execute stored procedure call //A paraméterek tömbje 0-tól indexelődik Console.WriteLine("Eljárás eredmény: " + command.parameters[1].value);
II/5 Tárolt függvény hívás void FunctionCall() //Megadott színű autók átlagárának lekérdezése command.commandtext = "create or replace function C#_atlagarfv " + "(sz in char) return number is " + "atl number(10,2); " + "begin " + "select avg(ar) into atl from auto_c# where trim(szin) = sz; " + "return atl; " + "end;"; Console.WriteLine("Tárolt eljárás létrejött"); command = new OracleCommand("C#_atlagarfv", con); command.commandtype = System.Data.CommandType.StoredProcedure; //Sample of how to bind parameters to the Stored Procedure OracleParameter szinin = new OracleParameter("sz", OracleType.VarChar); Console.Write("Milyen színű autók átlagárát kérdezed? "); szinin.value = Console.ReadLine(); szinin.direction = System.Data.ParameterDirection.Input; command.parameters.add(szinin); OracleParameter atlout = new OracleParameter("atl",OracleType.Number); atlout.direction = System.Data.ParameterDirection.ReturnValue; command.parameters.add(atlout); //Execute stored procedure call //A paraméterek tömbje 0-tól indexelődik Console.WriteLine("Függvény eredmény: " + command.parameters[1].value); III. Tranzakciókezelés Feladat: az összes autó árának megadott értékkel csökkentése. Ezt egy update utasítás hívásával meg tudjuk oldani, de nem biztos h. minden rekord esetén elvégezhető a módosítás az ar>0 integritási feltétel miatt. Ha van ilyen rekord, akkor a többi módosítást is vissza kell vonni. Egyébként véglegesítésre kerül az árak csökkentése. void OracleTransaction( ) OracleTransaction mytrans; // Start a local transaction mytrans=con.begintransaction(system.data.isolationlevel.readcommitted);
// Assign transaction object for a pending local transaction command.transaction = mytrans; command.commandtext = "update auto_c# set ar=ar-:csokkentes"; command.parameters.add("csokkentes", OracleType.Double); Console.WriteLine("Mennyivel csökkentsük az autók árát? "); command.parameters["csokkentes"].value = double.parse(console.readline()); mytrans.commit(); Console.WriteLine("Sikeres árcsökkentés"); mytrans.rollback(); Console.WriteLine("Árcsökkentés nem lehetséges");