Aplicatia User Connect

I . INTRODUCERE

Sistemul de Gestiune a Bazelor de Date (SGBD) prezintă sisteme informatice (sisteme software) specializate în stocarea și prelucrarea unui volum foarte mare de date. Un Sistem de Gestiune a Bazelor de Date (Database management system – DBMS), este un set complex de programe ce permite păstrarea, organizarea, extragerea datelor din bazele de date. SGBD-urile utilizează anumite modele conceptuale pentru a putea gestiona informațiile: ierarhic, rețea, relațional, obiectual și obiectual relațional.

Termenul "bază de date" se referă la datele de prelucrat, iar termenul de "gestiune" se referă la acțiunea de memorare și prelucrare a acestor date.

Sistemul de Gestiune a Bazelor de Date (SGBD) prezintă sisteme informatice (sisteme software) specializate în stocarea și prelucrarea unui volum mare de date, în rezolvarea problemelor de tip din clasificarea anterioară, volumul de prelucrări implicat fiind relativ mic.

Istoria SGBD-urilor începe odată cu apariția primelor suporturi magnetice de memorare – benzile magnetice – pe care informația era memorată secvențial, aceasta dând și caracterul secvențial al accesului de date în cadrul acestor sisteme. Aceasta etapă de dezvoltare este caracterizată de o identitate perfectă între structura logicăși cea fizică a informației din bazele de date, ceea ce a dus la o manipulare greoaie a datelor.

Apariția sistemelor de memorare de tipul discului magnetic a dus la o nouă etapă în dezvoltarea SGBD-urilor, caracterizate în principal prin: apariția accesului direct, odată cu cel secvențial, acesta având ca efect imediat o creștere foarte mare a vitezei de acces la date; separarea nivelului logic de cel fizic, astfel realizând o independență logică a datelor. În această etapă s-au dezvoltat tehnici avansate de selectare, grupare, prelucrare a datelor din bazele de date. În continuare sistemele de memorare s-au dezvoltat în direcția creșterii performanțelor acestora: capacități mult mai mari de memorare și viteze mult mai mari de accesare a datelor memorate în bazele de date (discul optic, casetele magnetice, CD-urile, etc).

I.

Sisteme de gestiune a bazelor de date

Clasificarea Sistemelor de gestiune a bazelor de date

Pentru descrierea structurilor datelor, precum și a relațiilor dintre acestea intr-o bază de date se utilizează un procedeu formal, denumit modelul conceptual. În practica prelucrării automate a datelor s-au consacrat următoarele modele conceptuale: 
– ierarhic
– rețea
– relațional.

Modelul ierarhic

Se bazează pe structuri de reprezentare arborescente și tipuri de relații unu la unu și unu la n. Cu ajutorul acestui model, structura bazei de date poate fi reprezentată sub forma unei structuri arborescicole – cu un nod rădăcină (trunchiul) și celelalte noduri (ramuri) care conțin colecțiile de date. Legăturile între noduri reflectă relațiile de asociere între înregistrările (set de date cu aceleași proprietăți) colecțiilor de date superioare și inferioare.

Modelul ierarhic are următoarele caracteristici:

. accesul direct este posibil numai la înregistrările din colecția de date rădăcină
. accesul la înregistrările colecțiilor de date inferioare se face prin specificarea tuturor colecțiilor, care se gasesc pe drumul de la colecția rădăcină până la colecția cercetată
. toate înregistrările din colecțiile bazei de date, cu excepția colecției de date rădăcină au câte o înregistrare superioară.

Se definește în acest fel o relație, care asigură consultarea înregistrărilor din colecțiile de date de la stânga spre dreapta și de sus în jos (modul "top-down").
Modelul ierarhic are unele limite, în special la operațiile de actualizare (modificarea valorilor) a bazei de date, deoarece adăugarea de înregistrări se poate face numai cu precizarea colecției de date superioare (cu excepția colecției de date radacină), iar ștergerea unei înregistrari generează ștergerea tuturor înregistrarilor subordonate.

Modelul rețea

Se bazează pe structura de reprezentare rețea și tipuri de relatii unu la unu, unu la n și m la n. O rețea este formată din mai multe noduri legate între ele. În modelul rețea al unei baze de date, fiecare nod reprezintă o colecție de date iar legaturile reflectă relațiile de asociere. Caracteristica principală este aceea că acceptă ca oricare colecție de date sa se situeze pe nivelul 1, prin indicarea explicită a relațiilor dintre acestea. În plus, acceptă existența temporară a înregistrarilor fără legături cu alte înregistrări și permite reprezentarea unică a înregistrărilor în baza de date.
Modelul rețea este un model complex, dificil de folosit, ocupă spațiu de memorie ineficient și dependențele din rețea sunt puțin clare, din cauza existenței mai multor relații de subordonare.

Modelul relațional

Modelul relațional este și va rămâne o lungă perioadă de timp (după spusele mai marilor în ale bazelor de date), cel mai utilizat model conceptual. Cel ce a dezvoltat acest model a fost Edgar Frank "Ted" Codd (23 August 1923 – 18 Aprilie 2003) – un specialist de origine britanică ce a adus contribuții semnificative în știința calculatoarelor. Modelul relațional a luat naștere când E.F.Codd lucra la IBM (anii ’70), perioadă în care a publicat un articol „A Relational Model of Data for Large Shared Data Banks” în care a enunțat treisprezece reguli ce vizează modelul relațional.

O bază de date reprezintă o colecție de date utilizată într-o organizație, colecție care este automatizată, partajată, definită riguros (formalizată) și controlată la nivel central.
O bază de date relațională (BDR) poate fi definită ca un ansamblu de tabele; fiecare tabel, alcătuit din linii (tupluri), are un nume unic și este stocat pe suport extern (de obicei disc). La intersecția unei linii cu o coloană se găsește o valoare atomică.

Conform acestui model, conceperea structurii bazei de date depinde exclusiv de legaturile între obiecte ce permit o descriere simpla sub forma tabelară.
Acest model de reprezentare a datelor se bazează pe noțiunea matematică de relație. O relație R este o submulțime a produsului cartezian de n mulțimi numite domenii (Di), n fiind gradul relației. O bază de date relațională este o multime de relații, legate prin domenii de definiție comune.

Modelul relațional a fost introdus pentru a elimina restricțiile impuse de către modelul rețea asupra legăturilor între colecțiile de date. Anumite legături pot să nu existe la un moment dat și să apară după aceea. În aceste condiții în mdelul rețea structura datelor trebuie modificată, ceea ce nu este cazul modelului relational, unde numai legăturile între colecții sunt semnificative. În concluzie, o relație poate fi reprezentată printr-un tabel, în care, fiecare rând reprezintă o înregistrare distinctă (un tuplu), iar fiecare coloană un domeniu, prin respectarea următoarelor reguli:
– fiecare rând al tabelului trebuie sa fie diferit de celelalte rânduri și formează un tuplu;
– ordinea rândurilor in tabel nu este predefinită putând fi modificata fără restricții;
– coloanele tabelului sunt identificate prin nume distincte, reprezentând câmpurile modelului relațional;
– fiecare valoare a unui câmp este reprezentată printr-un șir de caractere;
– în fiecare coloană a tabelului, valorile sunt de același fel, constituind un domeniu.

Orice tuplu al relației este identificat prin intermediul unei chei primare, care este definită printr-un câmp sau un grup de câmpuri cu valori unice.
Cu ajutorul modelului relațional structura conceptuală a bazei de date poate fi reprezentată sub forma unei mulțimi de tabele, care se asociază între ele prin intermediul unor chei.
Cele mai importante avantaje ale mdelului relațional sunt:
– este ușor accesibil pentru persoanele mai putin inițiate in informatică, datorită faptului că baza de date este reprezentată simplu ca o colecție de tabele;
– este un mdel omogen de reprezentare a legăturilor dintre colecțiile de date, numai prin relații;
– asigură independența programelor față de structura datelor, datorită simplificării structurii conceptuale și logice;
– permite proiectarea unei structuri optime a datelor, eliminând redundanța și anomaliile de actualizare;
– admite satisfacerea cerințelor întâmplătoare ale utilizatorilor.

"Un tuplu (sau o linie) este alcătuit din mai multe câmpuri (coloane sau atribute) și regrupează informații referitoare la un obiect, eveniment etc. ( de exemplu, informații referitoare la o entitate: o carte, un student, o localitate, un angajat al unei firme, o factură emisă etc.) Ordinea tuplurilor nu prezintă importanță din punctul de vedere al conținutul informațional al tabelei."

Teoria relațională evidențiază că nu pot exista două linii identice într-un tabel. Identificarea unei linii se face prin intermediul atributelor (câmpurilor) care o compun (valorile lor trebuie să fie unice).

Cheia primară a unei tabele este un atribut sau un ansamblu de atribute care identifică fără ambiguitate fiecare înregistrare. Există și câteva restricții în privința cheilor primare: unicitate (să permită identificarea unui singur tuplu dintr-o tabelă), compoziție minimală (în cazul în care cheia primară este compusă din mai multe atribute, nici un atribut din cheie să nu poată fi eliminat fără a distruge condiția de unicitate a înregistrărilor), valori non-nule (numită și restricție a entității – valorile atributelor sau ansamblurilor de atribute, nu pot lua decât valori ne-nule).

Un alt lucru important în bazele de date relaționale îl reprezintă organizarea tabelelor. Nominalizarea reprezintă procedeul prin care datele sunt grupate pe tabele distincte. Acest procedeu presupune parcurgerea unor etape de transformare succesive, până când baza de date este adusă la o formă optimizată. Se poate spune doar că există cinci forme de normalizare, fiecare pas în normalizare presupune aducerea bazei de date la o formă standard. Principalele obiective ale normalizării sunt reducerea pe cât mai mult posibil a redundanței datelor și eliminarea anomaliilor apărute la inserare, modificare, ștergere.

Prima formă de normalizare – presupune eliminarea câmpurilor compuse și pe cele repetitive;

A doua formă de normalizare – presupune eliminarea dependențelor funcționale parțiale;

A treia formă de normalizare – presupune eliminarea dependențelor funcționale tranzitive;

A patra formă – presupune eliminarea dependențelor multivaloare;

A cincea formă – elimină dependențele de joncțiune.

Datele unei baze de date pot fi exploatate prin intermediul limbajului de interogare SQL (Structured Query Language). Acesta este un limbaj standardizat ce este folosit de majoritatea sistemelor de gestiune a bazelor de date.

Prin intermediul acestui limbaj se pot:

se pot crea baze de date și tabele;

se pot realiza indecși;

se pot stabili relații între tabele;

se pot extrage și modifica date.

II. MSSQL Server

Codul de bază pentru Microsoft SQL Server își are originile în Sybase SQL Server și a reprezentat intrarea Microsoft pe piața bazelor de date pentru întreprinderi, concurând cu Oracle, IBM și Sybase. Microsoft, Sybase si Ashton-Tate s-au unit pentru a crea și a scoate pe piață prima versiune numita SQL Server 4.2 pentru Win OS/2. Ulterior, Microsoft a negociat pentru drepturi de exclusivitate la toate versiunile de SQL Server scrise pentru sistemele de operare Microsoft. Sybase și-a schimbat ulterior numele în Adaptive Server Enterprise, pentru a evita confuzia cu Microsoft SQL Server.

SQL Server 7.0 a fost primul server de baze de date bazat pe GUI (graphical user interface). O variantă de SQL Server 2000 a fost prima variantă comercială pentru arhitectura Intel.

Microsoft SQL Server este sistemul de gestiune a bazelor de date produs de către compania Microsoft. Pe o mașină fizică putem găzdui mai multe instanțe MSSQL.
O instanță MSSQL poate găzdui mai multe baze de date.

Efectiv o bază de date poate fi compusă din mai multe fișiere. 
Fișiere pot fi:

.mdf – întâlnite și sub denumirea de primary files sau main files. Acest fișier găzduiește obiectele unei baze de date (proceduri stocate, tabele, declanșatori, etc.). O bază de date poate să aibă cel mult un fișier .mdf.

.ndf – secondary database file. În principal fișierul .ndf este folosit în cazul optimizărilor. Spre exemplu: anumite tabele pot fi salvate în fișiere .ndf, fișiere ce vor fi găzduite în locații diferite, pe discuri diferite. Nu există restricții pentru o bază de date în cazul fișierelor .ndf.

.ldf – transaction log files – acest fișier păstrează un istoric al operațiunilor efectuate asupra informațiilor din baza de date.

Protocoale

Shared Memory: este cel mai simplu protocol de comunicație cu MSSQL (nu necesită configurări). Accesul la o instanță MSSQL prin intermediul Shared Memory poate fi făcut doar dacă resursa care accesează instanța MSSQL se află pe aceeași mașină pe care există și sistemul de gestiune a bazei de date. În general se apelează la Shared Memory în momentul în care celelalte protocoale de comunicație sunt dezactivate sau greșit configurate.

Named Pipes: acest protocol este indicat a fi folosit în cazul rețelelor locale, sau în cazul local named pipes (caz în care resursa care accesează instanța MSSQL este găzduită pe aceeași mașină pe care este găzduit și SGBD-ul).

TCP/IP: acest protocol este indicat a fi folosit în cazul WAN (wide area networks), a rețelelor dial-up, … . În cazul LAN-urilor (Local Area Network), diferențele dintre Named Pipes și TCP/IP sunt foarte mici, dar e important de știut faptul că o instanță MSSQL poate fi configurată să folosească mai multe protocoale simultan.

VIA: Virtual Interface Adapter – folosit în cazul conectării cu hardware specializat și în cazurile în care canalul de comunicație este unul dedicat. Sunt foarte rare cazurile în care este necesar a se configura și utiliza acest protocol.

Porturi

În general, portul folosit de instanța implicită MSSQL este TCP 1433.
UDP 1434 este folosit de serviciul SQL Server Browser.

În cazul în care este nevoie, portul instanței MSSQL poate fi stabilit de către sysadmin (altul decât TCP 1433).

Pot fi și situații în care portul să fie alocat dinamic. Mai exact, acest lucru este întâlnit atunci când pe același server găzduim mai multe instanțe MSSQL. În cazul instanțelor MSSQL putem avea de-a face cu instanțe MSSQL implicite (default instance) sau instanțe cărora le-a fost alocat un nume (named instance)- instanță denumită). Pe un server putem avea maxim o instanță implicită și zero sau mai multe instanțe denumite. 
În cazul în care pe un server se instalează mai multe instanțe MSSQL, există două posibilități:

pentru fiecare instanță în parte să fie alocate porturi statice;

MSSQL să aloce porturi în mod dinamic (asta înseamnă că portul instanței MSSQL să fie alocat la fiecare repornire a instanței – deci nu se poate garanta că de fiecare dată va fi alocat același port TCP);

În aceste cazuri, SQL Server Browser își intră în rol și va putea răspunde cererilor venite de pe rețea, astfel încât să informeze clienții de portul alocat unei anumite instanțe denumite.

Doar instanțele denumite (named instances) pot fi configurate a li se aloca porturi în mod dinamic (caz în care serviciul SQL Server Browser este necesar a fi pornit și publicat). Dacă există o singură instanță implictă, se poate renunța la serviciul SQL Server Browser (implicit instanța inițială este configurată să folosească TCP 1433).

Servicii MSSQL

Pe lângă rolul de sistem de gestiune a bazelor de date, MSSQL (în funcție de ediție) poate oferi și servicii precum:

Service Broker;

Replication Services;

Analysis Services;

Reporting Services;

Notification Services;

Integration Services;

Full Text Search Service;

Ediții MSSQL 2008

Enterprise

Standard

Workgroup

Web

Developer

Express

Compact 3.5

Ultima ediție MSSQL Express disponibilă ăn acest moment este Microsoft SQL Server 2008 R2 Express Edition. Această versiune MSSQL poate fi folosită atât în procesul de învățare cât și în cazul distribuției de software.
Totuși, acestei ediții i-au fost aduse intenționat anumite limitări:

max 1 CPU;

max 1 GB;

4 GB storage / per bază de date (exceptând fișierele log);

Maximum Capacity Specifications for SQL Server 2008

Instrumente necesare:

SQLCMD – este utilitarul de linie de comandă prin intermediul căruia se pot efectua diferite operații cu MSSQL (permite execuția scripturilor, apelarea comenzilor SQL, …). SQLCMD este utilitarul introdus odată cu Microsoft SQL Server 2005 și este succesorul lui OSQL (utilitar cu funcții asemănătoare apărut odată cu versiunea mai veche Microsoft SQL Server 2000). Se poate folosi și OSQL în cazul MSSQL Server 2005, MSSQL Server 2008, insă OSQL nu acoperă în totalitate funcționalitățile SQLCMD.

SQL Server Management Studio – este utilitarul cu interfață grafică utilizator și este ideal în cazul manipulării unei instanțe MSSQL. Trebuie știut faptul că SQL Server Management Studio poate fi găsit și în versiune Express, versiune care poate fi folosită gratuit (evident, spre deosebire de SQL Server Management Studio, versiunea Express are anumite limitări).

Business Intelligence Development Studio – este mediul integrat de dezvoltare ce este folosit în special pentru manipularea data mining, cuburilor OLAP, reporting services, etc.

Descărcarea kit-urilor de instalare

Microsoft SQL Server 2008 R2 RTM – Express;

Microsoft SQL Server 2008 R2 RTM – Management Studio Express;

Microsoft SQL Server 2008 Command Line Utilities

X86 Package;

X64 Package;

IA64 Package;

Microsoft SQL Server 2008 R2 RTM – Express with Management Tools;

Microsoft SQL Server2008 R2 RTM – Express with Advanced Services;

Instalarea Microsoft SQL Server 2008 R2 Express Edition

Doar pentru a completa anumite posibile scenarii, pot fi instalate două instanțe MSSQL – ambele în ediție EXPRESS.

În cazul primei instanțe MSSQL vor fi urmati pașii impliciți ai wizard-ului, iar instanța va fi una denumită – WEB01\SQLEXPRESS.

În cazul celei de-a doua instanțe MSSQL, în etapa de instalare va fi configurată instanța ca fiind instanță implicită – WEB01. Aici WEB01 este denumirea NETBIOS a mașinii pe care se efectuează instalarea. Instalarea se va efectua pe baza kit-ului de instalare Microsoft SQL Server 2008 R2 RTM – Express with Management Tools.

Instalarea Microsoft SQL Server 2008 R2 necesită prezența pachetelor:

Microsoft .NET Framwework 3.5 SP1;

Microsoft Windows Installer 4.5;

Microsoft Windows PowerShell;

T-SQL (Transact-SQL)

Transact-SQL este o extensie a limbajului SQL ce permite adăugarea în (mod programatic) de funcționalități ce nu sunt definite implicit în SQL. Cu ajutorul T-SQL se pot defini variabile, proceduri stocate, funcții, se pot controla excepții, etc.

Tranzacții SQL

– Sunt parte integrantă a sistemelor de gestiune a bazelor de date relaționale

– Ajută la definirea unei singure unități de execuție

– O tranzacție poate conține una sau mai multe instrucțiuni SQL care sunt executate sau

anulate ca un tot unitar. Aceasta ajută la prevenirea unor actualizări parțiale sau a unor date în stare inconsistentă

Actualizare parțială reprezintă o parte a unui proces care este anulat fără a anula toate celelalte părți ale aceluiași proces .

Tranzacțiile respectă regula ACID:

Atomicity

Consistency

Isolation/Independence

Durability

Regula ACID

Atomicity – tranzacțiile sunt o entitate de tipul “totul sau nimic” – făcîndu-se toți pașii sau nici unul

Consistency – asigură faptul că datele sunt valide atât înainte cât și după tranzacție. Trebuie păstrată integritatea datelor precum și structura internă a datelor trebuie să fie într-o stare validă

Isolation – o tranzacție nu trebuie să fie dependentă de o altă tranzacție care poate să aibă loc în mod concurent. O tranzacție nu trebuie să aibă acces la datele altei tranzacții ce este într-o stare intermediară. Trebuie să vadă datele așa cum au fost înainte de începerea tranzacției sau după încheierea acesteia.

Durability – efectele tranzacției sunt fixate după ce tranzacția este executată, și orice modificări vor putea fi anulate după un eșec al sistemului.

Există trei tipuri de tranzacții: Autocommit – implicit; explicit; implicit

Autocommit – fiecare comandă SQL este o tranzacție de sine stătătoare care se execută imediat

Exemplu: două comenzi INSERT pentru debitarea/creditarea unui cont

Exemplu: ștergerea datelor dintr-o tabelă – această operațiune nu mai poate fi anulată

Implicit – acest mod este activat cu comanda:

SET IMPLICIT_TRANSACTIONS ON

Pentru a-l dezactiva :

SET IMPLICIT_TRANSACTIONS OFF

Cu modul Implicit activat oricare din comenzile de mai jos va deschide în mod automat o tranzacție care rămâne deschisă până la executarea comenzilor COMMIT sau ROLLBACK

Comenzi care generează tranzacții implicite: ALTER TABLE, FETCH, REVOKE, CREATE , GRANT, SELECT, DELETE, INSERT, TRUNCATE TABLE, DROP, OPEN, UPDATE

Explicit – sunt cele pe care le definește programatorul SQL

Acesta este modul recomandat pentru tranzacții

Se poate controla cu exactitate care sunt instrucțiunile ce aparțin unei tranzacții și acțiunile pe care să le întreprindem dacă apar erori.

@@TRANCOUNT – numărul de tranzacții active pe o conexiune

BEGIN TRANSACTION – incrementează valoarea

ROLLBACK TRANSACTION și COMMIT TRANSACTION decrementează valoarea ROLLBACK TRAN la un savepoint nu are nici un efect asupra valorii

BEGIN TRANSACTION – stabilește punctul de pornire al unei tranzacții explicite

ROLLBACK TRANSACTION – Readuce datele la starea inițială – de le începutul tranzacției. Orice modificări asupra datelor sunt anulate. Resursele alocate tranzacției sunt eliberate.

COMMIT TRANSACTION – termină tranzacția dacă nu a fost nici o eroare și modificările devin permanente. Resursele sunt eliberate.

SAVE TRANSACTION – stabilește un punct de salvare într-o tranzacție. Se definește un punct la care se poate întoarce o tranzacție în cazul în care o parte a tranzacției este anulată. (Nu vor fi anulate toate comenzile din tranzacție)

O tranzacție trebuie anulată sau executată imediat după o întoarcere la un SAVEPOINT

Funcția sistem @@ERROR întoarce valoarea erorii pentru ultima instrucțiune executată în contextul conexiunii curente

Exemplu – nu se va insera nici o înregistrare

Dacă o tranzacție rămâne deschisă poate bloca alte procese în a efectua activități asupra datelor modificate

DBCC OPENTRAN – identifică cea mai veche tranzacție activă

Locking

Blocarea este o parte normală și necesară a unui sistem de gestiune a bazelor de date relațional. Asigură integritatea datelor prin interzicerea actualizărilor concurente asupra acelorași date și prin interzicerea vizualizării unor date ce sunt in curs de actualizare.

Ajută la prevenirea apariției problemelor legate de concurență :

– când un user încearcă să citească date modificate de altul

– când un user incearcă să modifice date pe care altul le citește

– când un user incearcă să modifice date pe care altul încearcă să le modifice

Lock – sunt plasate asupra resurselor SQL Server

Lock mode – reprezintă modul în care este blocată o resursă

Shared lock – plasat în timpul interogărilor read-only, care nu modifică datele.

Alte procese pot citi dar nu pot actualiza datele

Lock mode :

– Intent lock – se creează o coadă de lock-uri, ce desemnează ordinea conexiunilor și a drepturilor asociate de actualizare sau citire asupra resurselor. Se folosesc pentru a indica intenții viitoare de a bloca o anumită resursă

– Update lock – sunt puse obținute înainte de a face actualizări. Când se modifică o înregistrare se transformă în exclusive lock. Dacă nu se face modificare se trece la shared lock. Acest tip de lock previne deadlock-uri

– Exclusive lock – orice altă operație asupra resurselor este oprită. (la INSERT, UPDATE, DELETE) :

– > Schema modification – când se execută operații DDL

– > Schema stability – la compilarea unei interogări. Nu se pot face operații DDL

– > Bulk update – la operații de copiere bulk – un volum mare de date. Crește performanța de copiere, scade concurența Key-range – protejează un interval de înregistrări pe baza unei chei de indexare.

Lock se poate pune pe orice tip de resursă – de la o înregistrare până la tabelă sau bază de date. Orice lock necesită memorie.

Resurse asupra cărora se pun lock-uri:

– Allocation unit – o mulțime de pagini grupate după tip de date

– Application – o resursă specificată de aplicație

– DB – toată baza de date

– Extent – o unitate de alocare de 8 KB

– File – fișierul bazei de date

– HOBT – heap sau B-tree (o tabelă fără un index de tip clustedered)

– Metadata

– Key – asupra unui index

– Object – un obiect al bazei de date (view, procedură stocată, funcție)

– Page – o pagină de date de 8KB sau o pagină de index

– RID – row identifier

– Table

Nu toate tipurile de lock-uri sunt compatibile una cu alta.

Nu se pot pune alte lock-uri pe o resursă care are un exclusive lock .

Pe o resursă care are un update lock se poate pune doar un shared lock de către o altă tranzacție. Pe o resursă care are un shared lock se pot pune alte shared sau update lock.

Locking – tranzacții concurente

Isolation – ACID

Izolarea tranzacțiilor – reprezintă gradul la care modificările făcute de o tranzacție pot fi văzute de o altă tranzacție – în condiții de acces concurent la baza de date. Acest grad poate varia.

ANSI / ISO SQL definește 4 tipuri de interacțiune între tranzacții concurente:

1. Dirty reads – procesul prin care o tranzacție modifică o valoare și o alta o citește înainte de commit. În cazul unui rollback în prima tranzacție se vor citi date care nu se salvează în baza de date.

2. Non-repeatable reads – procesul prin care o tranzacție actualizează date și altă tranzacție citește datele. Datele citite înainte de actualizare și după actualizare vor fi diferite

3. Phantomreads – procesul prin care o tranzacție citește de două ori. Între cele două operații de citire are loc o operație de actualizare (inserare/ștergere). Rezultatele celor două citiri vor fi diferite

4. Lost updates – când două tranzacții actualizează o valoare. Ultima tranzacție care se execută “câștigă”. Prima actualizare se pierde.

Pentru a evita aceste probleme de concurență SQL Server definește niveluri de izolare.

READ COMMITTED (implicit) – se folosesc shared locks

READ UNCOMMITTED – cel mai puțin restrictiv. Oferă cel mai mare nivel de concurență și cel mai mic nivel de integritate a datelor. Util pentru date relativ statice – crește performanța

REPEATABLE READ – nu sunt permise dirty și non-repeatable reads

Niveluri de izolare:

SERIALIZABLE – setarea cea mai restrictivă. Nu se permite inserări/modificări care ar afecta rezultatul unei interogări

SNAPSHOT – permite citirea unei versiuni a datelor așa cum au existat la începutul tranzacției

SET TRANSACTION ISOLATION LEVEL

{

READ UNCOMMITTED

READ COMMITTED

REPEATABLE READ

SNAPSHOT

SERIALIZABLE

}

Tranzacții – Blocking

Blocarea are loc atunci când o tranzacție pune "lock" pe resurse pe care alte tranzacții vor să le citească sau să le modifice .

Blocările pe termen scurt în general sunt în regulă și de așteptat pentru aplicații intensive .

Aplicațiile proiectate defectuos pot cauza blocări de termen lung care păstrează lock-uri pe resurse și blochează alte sesiuni să citească sau să actualizeze date.

Un proces blocat rămâne blocat nedefinit sau până când :

– expiră (pe baza SET LOCK_TIMEOUT),

– serverul este oprit,

– procesul este oprit,

– conexiunea termină actualizările

Motivele pentru care poate apare blocare pe termen lung:

a ) Lock-uri excesive pe liniile unei tabele fără index poate determina SQL Server să obțină un table lock, blocând alte tranzacții ;

b ) Aplicațiile deschid o tranzacție, după care așteaptă date de intrare de la utilizator în timp de conexiunea rămâne deschisă ;

c ) Aplicațiile folosesc tranzacții prea lungi care actualizează multe înregistrări sau multe tabele într-o tranzacție (împărțirea unei tranzacții mari în mai multe mici poate fi mult mai eficientă) .

Identificarea problemelor de blocare:

sys.dm_os_waiting_tasks DMV – pentru identificarea procesului ce a cauzat blocarea

Pentru identificarea textului comenzii care au cauzat blocarea

sys.dm_exec_sql_text

sys.dm_exec_connections

KILL {spid | UOW} [WITH STATUSONLY] – oprește o sesiune activă – se folosește doar când alte metode nu dau rezultate

Spid -> id-ul de sesiune asociat cu conexiunea activă ce trebuie oprită

Când o tranzacție/instrucțiune este blocată așteaptă ca un lock pe o resursă să fie eliberat SET LOCK_TIMEOUT specifică timpul de așteptare înainte de a returna eroare

Sintaxa: SET LOCK_TIMEOUT timeout_period (în ms)

Tranzacții – Deadlock

Deadlock-ul are loc atunci când:

– Prima sesiune are un lock pe resurse ce trebuie modificate de către a doua sesiune

– A doua sesiune are un lock pe resurse ce trebuie modificate de către prima sesiune

– Niciuna din cele două sesiuni nu poate continua

– Una din sesiuni va fi aleasă ca deadlock victim

– Sesiunea va fi oprită și tranzacția anulată

Motive pentru care apare deadlock:

– Aplicația accesează tabele în ordine diferită

De exemplu: Prima sesiune actualizează tabelul Clienți și apoi Comenzi, iar a doua sesiune actualizează Comenzi și apoi Clienți

– Aplicația folosește tranzacții lungi ce actualizează mai multe linii sau mai multe tabele

Identificare deadlock:

DBCC TRACEON ( trace# [ ,…n ][ ,-1 ] ) [ WITH NO_INFOMSGS ]

DBCC TRACESTATUS ( [ [ trace# [ ,…n ] ] [ , ] [ -1 ] ] ) [ WITH NO_INFOMSGS ]

DBCC TRACEOFF ( trace# [ ,…n ] [ , -1 ] ) [ WITH NO_INFOMSGS ]

trace# – indică una sau mai multe numere trace flag ce trebuie activate/dezactivate/verificate -1 activare/dezactivare/verificare globală

Se pot mări șansa ca o sesiune să fie aleasă ca victimă pentru deadlock

SET DEADLOCK_PRIORITY { LOW | NORMAL | HIGH | }

Va fi aleasă ca victimă sesiunea cu valoarea cea mai mică ( prioritatea numerică – valori de la -10 la 10 ) .

COMENZI SQL

SQL Server folosește carcaterul apostrof pentru a delimita valorile de tip text/string . Majoritatea SGBD-urilor acceptă și ghilimele.

Valorile numerice nu se delimitează cu apostroafe/ghilimele .

CREATE DATABASE

Folosit pentru a crea o nouă bază de date

Sintaxa: CREATE DATABASE database_name

Exemplu: CREATE DATABASE posdatabase

CREATE TABLE

Folosit pentru a crea tabele

Sintaxa: CREATE TABLE table_name ( column_name1 data_type, column_name2 data_type, column_name3 data_type, …. )

Tipul de date stabilește ce tip au valorile pentru coloana respectivă (tipuri de date MSMSQL)

SELECT – Căutare informații in baza de date

Clasificare comenzi SQL

Grup DML (Data Manipulation Language)

UPDATE – Modifică conținut înregistrări dintr-o tabelă

INSERT INTO – Adăugă inregistrarile intr-o tabelă

DELETE FROM – Șterge înregistrările dintr-o tabelă

Grup DDL (Data Definition Language)

CREATE obiect – Crează structură tabelă, index

ALTER obiect – Modifică caracteristici tabelă,index,sesiune,user,roll,..

DROP obiect – Șterge tabelă, trigger, index, secvență, vedere..

RENAME obiect – Redenumește tabelă sau viewlayer

TRUNCATE TABLE – Șterge toate înregistrarile dintr-o tabelă

Grup Control tranzacții

COMMIT – Confirmă terminare tranzactie

ROLLBACK – Reface toate modificarile BD de la inceputul tranzactiei (ultimul COMMIT)

SAVEPOINT – Creează un punct de reluare in tranzactie

Grup DCL (Data Control language)

GRANT – Acordă drepturi pentru un anumit user

REVOKE – Retrage drepturi de la un anumit user

Descriere comenzi: O comandă se poate scrie pe mai multe randuri si se termină cucaracterul ";"

CREATE TABLE tabela (col1 tip1, col2 tip2,…..); – definește câmpuri tabelă

CREATE TABLE tabela AS SELECT * FROM tab2; – copiază altă tabelă

CREATE INDEX nume_index ON tabela(col1,col2,..); – creează index pentru o tabelă

CREATE INDEX inume ON pers (Nume); – creează index INUME pentru tabela PERS

ALTER TABLE tabela ADD (col1 tip1,col2 tip2,..); – adaugă valorile 1 și 2 pe coloanele 1 și 2

ALTER TABLE tabela MODIFY (col1 tip1,col2 tip2,..); – modifică valorile 1 și 2 pe coloanele 1 și 2

ALTER TABLE tabela DROP COLUMN col1,col2; – șterge coloanele 1 și 2 din tabelul "tabela"

Operatori logici

Proceduri stocate

O procedură stocată grupează una sau mai multe comenzi SQL într-o unitate logică, stocată ca un obiect al bazei de date.

Definiția procedurii este accesibilă din sys.sql_modules .

La prima execuție se creează un plan de execuție stocat în memoria cache de plan . Planul poate fi refolosit la execuții ulterioare

Reutilizarea planului permite performanțe mai bune în comparație cu interogările ad-hoc necompilate.

Avantajele folosirii de proceduri stocate:

– ajută la centralizarea codului SQL în data tier. Aplicațiile ce includ cod SQL ad-hoc sunt greu de întreținut.

– reduc traficul pe rețea pentru interogări ad-hoc formate din multe linii (e mai ușor și eficient să se trimită de la aplicație o singură linie pentru executarea unui proceduri stocate decât 500 de linii de cod SQL).

– încurajează reutilizarea codului

– permit obscurarea metodei de obținere a datelor; permite modificări la nivelul datelor fără a fi nevoie de modificarea codului la nivel de aplicație

– pot utiliza controlul accesului, tabele temporare, variabile de tip tabel etc.

– securitate sporită – procedurile stocate pot funcționa ca un nivel de control la date/tabele

Sintaxa pentru creare:

CREATE PROCEDURE [schema_name.] procedure_name AS { [ …n ] }

Sintaxa pentru executare:

EXEC [schema_name.] procedure_name

SET NOCOUNT ON – oprește transmiterea / afișarea mesajelor în legătură cu numărul de linii afectate de ultima comandă SQL

Funcția @@ROWCOUNT se va actualiza indiferent de setarea pentru NOCOUNT

=> Traficul prin rețea va fi redus – aplicația va fi mai rapidă

Proceduri stocate parametrizate

– Parametrii sunt prefixați de caracterul @

– Parametri sunt de două tipuri : de intrare – Input și de ieșire – Output care permit transferul de informații în rutina apelantă

– Parametrul poate specifica o valoare implicită caz în care la apel nu mai trebuie inclus

Dintr-o procedură stocată se pot transmite mai multe result-set-uri care pot fi consumate de aplicație.

Sintaxa creării unei proceduri stocate:

CREATE { PROC | PROCEDURE } [schema_name.] procedure_name [ ; number ] [ { @parameter [ type_schema_name. ] data_type } [ VARYING ] [ = default ] [ OUT | OUTPUT ] [READONLY] ] [ ,…n ] [ WITH [ ,…n ] ] [ FOR REPLICATION ] AS { [;][ …n ] | }

Modificarea unei proceduri stocate:

ALTER PROCEDURE

Se poate schimba orice în afară de nume

Eliminarea unei proceduri stocate:

DROP PROCEDURE { [ schema_name. ] procedure } [ ,…n ]

Executarea automată a unei proceduri stocate la pornirea SQL Server se face cu procedura stocată sistem sp_procoption și poate rula doar în baza de date master

Securitatea procedurilor stocate

Securitatea procedurilor stocate au avantaje inerente în ceea ce privește securitatea . Codul inline ad-hoc este mult mai afectat de atacuri de tip ‘SQL injection’.

Includerea codului SQL în procedurile stocate permite ascunderea lui de influențe externe .

Se poate controla modul în care sunt făcute modificările și modul în care sunt extrase datele.

“Criptarea” procedurilor stocate:

prin criptarea definiției nu se va putea accesa codul procedurii stocate

se previne modificarea procedurii stocate și operațiile de tip reverse-engineering.

Sintaxa:

CREATE PROCEDURE proc_name WITH ENCRYPTION AS …

Clauza EXECUTE AS

– stabilește contextul de securitate pentru procedura stocată

Context de securitate – reprezintă permisiunile user-ului ce execută procedura stocată

O procedură stocată poate fi executată:

– În contextul de securitate al apelantului

– De către user-ul care a creat/modificat procedura

– De către un anumit login

– De către proprietarul procedurii stocate

Logins

Selectarea unei baze de date

Selectarea unei baze de date se face prin intermediul comenzii USE.

USE [DATABASE]

GO

Principals and permissions

 În terminologia MSSQL:

Login: asociază un cont utilizator Windows sau un cont SQL.
Role: asemănător grupurilor de securitate Windows, rolurile au scopul de a grupa mai multe conturi și de a facilita accesul la resursele MSSQL.

Server roles:

bulkadmin: membrii acestui rol vor putea apela BULK INSERT (BULK INSERT – operație prin intermediul căreia pot fi importate date din diverse surse de date. Ex: fișiere .txt, .csv, etc. ).

dbcreator: membrii acestui rol vor putea crea baze de date, efectua modificări sau operații de restaurare asupra propriilor baze de date, etc.

diskadmin: membrii acestui rol vor avea drepturile necesare pentru a efectua operații cu fișiere (ex: ștergerea / crearea unui backup device).

processadmin: membrii acestui rol au posibilitatea de a vizualiza și întrerupe procesele MSSQL.

public: orice login va fi membru al acestui grup. Scopul acestui rol este de a ușura managementul accesului la resursele unei instanțe MSSQL.

securityadmin: membrii acestui rol pot administra login-urile, pot reseta parolele conturilor SQL, pot citi logurile MSSQL, … . Operațiile executate asupra login-urilor cu rol de sysadmin sunt limitate.

serveradmin: membrii acestui rol vor putea schimba parametrii de funcționare a instanței MSSQL.

setupadmin: membrii acestui rol au dreptul de a elimina / adăuga  linked servers, administra replicările, precum și de a executa anumite proceduri stocate în sistem. Linked servers – este o funcționalitate prin intermediul căreia este posibilă interogarea unor surse externe (ex: prin intermediul MSSQL, un set de date din instanța curentă poate fi joncționat cu un set de date obținut dintr-o foaie de lucru Excel).

sysadmin: membrii acestui rol au drepturi depline asupra instanței MSSQL.

Database roles:

db_accessadmin: membrii acestui rol pot șterge și adăuga login-urile respectivei baze de date (dar fără a avea posibilitatea de a asigna permisiuni).

db_backupoperator: membrii acestui rol pot realiza copii de siguranță asupra respectivei baze de date ( însă pentru a putea restaura baze de date, login-ul va trebui să fie membru dbcreator).

db_datareader: membrii acestui rol pot executa fraze SELECT-SQL asupra oricărui tabel sau view din respectiva bază de date.

db_datawriter: membrii acestui rol pot executa operații de scriere (ștergere / modificare / adăugare) asupra oricărui tabel din respectiva bază de date.

db_ddladmin: membrii acestui rol pot executa comenzi data definition language (DDL) asupra respectivei baze de date. DDL – creare/modificare/ștergere: tabel, trigger, index, function, stored procedure, etc.

db_denydatareader: membrii acestui rol nu pot efectua operații de citire asupra respectivei baze de date.

db_denydatawriter: membrii acestui rol nu pot efectua operații de scriere (ștergere / modificare / adăugare) asupra tabelelor respectivei baze de date.

db_owner: membrii acestui rol au drepturi depline asupra respectivei baze de date.

db_securityadmin: membrii acestui rol pot aduce modificări permisiunilor respectivei baze de date (dar nu pot șterge/adăuga login-uri). Atât db_securityadmin cât și db_accessadmin nu au drepturile necesare pentru managementul apartenenței login-urilor la anumite roluri specifice bazelor de date (pentru aceasta fiind necesare drepturile db_owner).

public: orice database-level login va fi membru al acestui grup.

Principals

Windows principals: login-uri care sunt asociate cu:

conturile de domain user ale windows-ului;

conturile locale de useri pentru windows;

grupurile de domeniu pentru windows;

grupurile locale windows;

SQL server principals: login-uri care sunt asociate cu conturile MSSQL (conturile sunt salvate în cadrul instanței MSSQL).

Database principals:

Database users: database-level login.

Database roles: rolurile menționate anterior (db_accessadmin, db_backupoperator, db_datareader, db_datawriter, db_ddladmin, db_denydatareader, db_denydatawriter, db_owner, db_securityadmin, public);

Listare “logins” și“server roles”

Listarea rolurilor se poate face și pe baza procedurii stocate sp_helpsrvrole.

Procedura SQL de mai sus poate fi parțial înlocuită de procedura stocată sp_helpsrvrolemember – pot fi făcute filtrări pe baza parametrului @srvrolename

Crearea unui login

Crearea unui login care să asocieze un cont Windows (contul Windows WEB01\iftvio trebuie să existe înainte de a fi creat login-ul).”

Crearea unui login care să asocieze un cont SQL:

a cărui bază de date implicită să fie baza de date master;

la prima autentificare parola trebuie să fie schimbată de către user;

DEFAULT_LANGUAGE = us_english;

se aplică politica de securitate referitoare la schimbarea parolei, complexitate, etc.

Se poate folosi procedura stocată sp_addsrvrolemember pentru ca login-ul “USIReader” să devină membru al rolului sysadmin .

Pentru revocarea rolului sysadmin pentru loginul “USIReader” – se poate folosi procedura stocată sp_dropsrvrolemember.

Modificarea unui login

Dezactivarea login-ul asociat contului Windows WEB01\iftvio

ALTER LOGIN

Ștergerea unui login

„Dezactivarea login-ul asociat contului Windows WEB01\iftvio.”

DROP LOGIN

După ce a fost creat login-ul, acesta poate fi mapat unei baze de date.

Login-ul WEB01\iftvio poate fi mapat la la baza de date “posdatabase”

CREATE USER

ALTER USER

Alocarea a drepturi depline asupra bazei de date “posdatabase” userului WEB01\iftvio.

Procedura: sp_addrolemember

Vizualizarea rolurilor (database-roles) alocate userului WEB01\iftvio

Procedura: sp_helpuser

Vizualizarea “database roles”

sp_helprole

Mai multe detalii legate de userii și rolurile de la nivelul bazei de date pot fi obținute prin intermediul procedurilor stocate  sys.database_role_members  și  sys.database_principals.

Revocarea drepturilor rolului db_owner pentru userul WEB01\iftvio pentru baza de date “posdatabase“

Procedura: sp_droprolemember

Ștergerea userul WEB01\iftvio din baza de date “ posdatabase”

DROP USER

Alocarea permisiunilor

Adăugarea userului USIReader pentru baza de date posdatabase

Userului USIReader îi va fi alocat:

doar dreptul de citire (selecție) asupra anumitorcoloane (StoreID, MyCityCode, ExternalStoreID, EffectiveCityCode) din tabela Stores;

doar dreptul de citire (selecție) asupra tabelei Cities;

doar dreptul de citire (selecție) asupra tabelei Countries;

dreptul de scriere (inserare, modificare, ștergere) și citire (selecție) asupra tabelei Machines;

doar dreptul de scriere (selecție) asupra tabelei StoreParams;

La final se vor lista permisiunile alocate userului USIReader.

GRANT

DENY

REVOKE

sp_helprotect

USE [posdatabase]

GO

CREATEUSER [USIReader] FORLOGIN [USIReader]

WITHDEFAULT_SCHEMA=[dbo]

GO

GRANTSELECTON [dbo].[Stores]([StoreID],

[MyCityCode],[ExternalStoreID],[EffectiveCityCode])TO [USIReader]

GO

DENYSELECTON [dbo].[Stores]([DefaultGateway])TO [USIReader]

GO

DENYSELECTON [dbo].[Stores]([DNSServer1])TO [USIReader]

GO

GRANTSELECTON [dbo].[Cities] TO [USIReader]

GO

GRANTSELECTON [dbo].[Countries] TO [USIReader]

GO

GRANTDELETEON [dbo].[Machines] TO [USIReader]

GO

GRANTINSERTON [dbo].[Machines] TO [USIReader]

GO

GRANTSELECTON [dbo].[Machines] TO [USIReader]

GO

GRANTUPDATEON [dbo].[Machines] TO [USIReader]

GO

GRANTSELECTON [dbo].[StoreParams] TO [USIReader]

GO

EXECsp_helprotect@username='USIReader'

GO

Revocarea permisiunilor acordate anterior userului USIReader

REVOKE

USE [Comanda]

GO

REVOKESELECTON [dbo].[Stores] TO [USIReader]

GO

REVOKESELECTON [dbo].[Cities] TO [USIReader]

GO

REVOKEDELETEON [dbo].[MAchines] TO [USIReader]

GO

REVOKEINSERTON [dbo].[MAchines] TO [USIReader]

GO

REVOKESELECTON [dbo].[MAchines] TO [USIReader]

GO

REVOKEUPDATEON [dbo].[MAchines] TO [USIReader]

GO

REVOKESELECTON [dbo].[Countries] TO [USIReader]

GO

REVOKESELECTON [dbo].[StoreParams] TO [USIReader]

GO

III . Aplicația „User Connect”

Descriere și rol

Aplicația „User Connect” este o aplicație dezvoltată cu ajutorul programului Microsoft Visual Studio în limbajul de programare C# (C Sharp).

Aplicația poate fi folosită de către administratorii de sistem în cadrul unei rețele de calculatoare din afacerile mici și mari în orice domeniu. Rolul aplicației este de a ușura conectarea utilizatorului la o bază de date centrală sau la una locală, pentru a vizualiza detaliile de rețea în vederea configurărilor și instalărilor viitoare.

Cerințe: – o rețea de calculatoare / servere

se va folosi versiunea de Microsoft SQL Server 2008

fiecare server conține o bază de date SQL cu detaliile tehnice locale .

Pentru fiecare server va exista o bază de date denumită “posdatabase”, care va conține urmatoarele tabele:

Cities

Countries

DistributionLines

MachineLinks

Machines

MachineTypes

RegionParams

Regions

StoreParams

Stores

Se creează userii necesari pentru această bază de date, în special userul “USIReader” care va fi folosit și de către aplicația “User Connect”. Userii default “guest” și “INFORMATION_SCHEMA” au fost dezactivați din motive de securitate.

Tabela “Countries” conține următoarele câmpuri:

CountryCode– PrimaryKey -(format din 3 litere – ex.: ROU pentru România)

CountryCode2 (format din 2 litere – ex.: RO pentru România)

CountryName

CountryPhoneCode (prefixul de telefon pentru țara respectivă)

CountryTimeZone (CET, WET, CST..)

CountryCode varchar(3)

CountryName varchar(30)

CountryPhoneCode int

CountryTimeZone varchar(3)

CountryCode2 varchar(2)

Tabela “Cities” conține următoarele câmpuri:

CityCode – Primary Key

CityName

MyRegionCode – Foreign Key cu tabela Region

MyRegionCode varchar(3)

CityName varchar(30)

CityCode varchar(3)

Tabela “Regions” conține următoarele câmpuri:

RegionCode – PrimaryKey -(format din 3 litere – ex.: ROU pentru România)

MyCountryCode – ForeignKey cu tabela Countries (format din 3 litere – ex.: ROU pentru România)

RegionName

LanguageCode (limbajul folosit in țara respectivă – format din 3 litere – ex.: rou – limba română)

RegionTimeZone (CET, WET, CST..)

RegionCode varchar(3)

RegionName varchar(50)

MyCountryCode varchar(3)

RegionTimeZone varchar(3)

LanguageCode varchar(3)

Tabela “RegionParams” conține următoarele câmpuri:

MyRegionCode (format din 3 litere – ex.: ROU pentru România)

Name

Value

MyRegionCode varchar(3)

Name varchar(50)

Value varchar(512)

Tabela “DistributionLines” arată dacă serverele respective sunt de test sau de producție șiconține următoarele câmpuri:

DistributionLineCode

DistributionLineName

DistributionLineCode varchar(2)

DistributionLineName varchar(30)

Tabela “Stores” conține toate detaliile tehnice necesare instalării serverului și conține următoarele câmpuri:

StoreID

MyCityCode – Foreign Key cu CityCode din tabela “Cities”

MyDistributionLineCode – Foreign Key cu DistributionLineCode din tabela ”DistributionLines”

StoreName

SubnetMask

DefaultGateway

DNSServer1

StoreTimeZone

StoreID bigint

MyCityCode varchar(3)

MyDistributionLineCode varchar(2)

StoreName varchar(30)

SubnetMask nvarchar(15)

DefaultGateway nvarchar(15)

DNSServer1 nvarchar(15)

Tabela “StoreParams” conține parametrii necesari pentru fiecare server și conține următoarele câmpuri:

UniqueID

Name

Value

UniqueID bigint

Name varchar(50)

Value varchar(512)

Tabela “Machines” conține detaliile necesare pentru fiecare mașină din locația respectivă– unele locații pot avea mai multe servere – conține următoarele câmpuri:

MAC

MyStoreID – ForeignKey cu StoreID din tabela Stores

MyType – server sau computer de alt tip

IPAddress

MAC char(12)

MyStoreID bigint

MyType varchar(3)

IPAddress varchar(15)

Funcționalitate

Aplicația “User Connect” folosește patru câmpuri principale și patru butoane principale.

Câmpuri:

OS DB– Operating system DataBase – dacă utilizatorul dorește să primească date de pe baza cemtrală, trebuie să introducă hostname-ul server-ului unde există această bază de date centrală

Server name– utilizatorul trebuie să introduca hostname-ul serverului de unde dorește să primească informațiile necesare (Eg.: ABC11MPS3000)

Non-standard user – deși aplicația se conecteaza cu user-ul default, dacă se dorește conectarea cu un alt user se introduce în acest câmp

Non-Standard password – parola pentru user-ul respectiv

Butoane:

Afișează magazin– afișează magazinul menționat

Caută magazin– acest buton deschide o altă fereastră unde utilizatorul poate să caute mai multe detalii despre un anume server din țara de unde dorește informațiile

CautăESL server– acest buton schimbă interfața aplicației pentru a putea căuta și alt tip de servere (Eg.: ESL – Electronic Service Labeling)

Schimbă culoarea – adaugă un pic de culoare aplicației, precum și mesaje de eroare mai amuzante

După ce se introduce numele serverului și se inițiază cautarea prin apăsarea butonului “Afișează magazin”, aplicația va returna detalii tehnice existente în tabelul SQL – “Machines” (store ID, MAC, IP Address, tipul mașinii respective) referitoare la server și la celelalte calculatoare legate la rețea.

De asemenea rezultatul returnat va conține detaliile din tabelul SQL “Region Params” – aceștia sunt parametrii generali care se aplică de fiecare dată cand un server este instalat în țara respectivă.

Rezultatul va conține de asemenea și parametrii care se aplică numai serverului respectiv –din tabelul SQL “Store Params” – cum ar fi : BackupServer – reprezintă un server de backup pentru serverul inițial unde se pot copia fișiere importante, ViewLayer version – versiunea de view-uri, UploadAI – parametru necesar pentru anumite tipuri de transfer de date între anumite server.

Butonul “Cauta ESL server” schimbă interfața aplicației pentru a putea căuta și alt tip de servere (Eg.: ESL – Electronic Service Labeling) ,

Ca exemplu s-a luat un server din Roma – ROM11ESL0100 . Acest tip de server este folosit pentru transferul etichetelor electronice de la sistemele inițiale unde sunt create, către echipamentele care folosesc acest tip de prețuri electronice.

De asemenea se pot observa detaliile tehnice ale severului – MAC, IP Address, precum și dacă are conectată o placă ILO – Integrated Lights-Out – folosită pentru diferite activități atunci când serverul fizic este offline. Aceasta poate fi accesată și de la distanță – Remote dacă se știu MAC –ul și IP Address.

Butonul „Schimbă culoarea” – adaugă un pic de culoare aplicației, precum și mesaje de eroare mai amuzante.

Caută magazin – acest buton deschide o altă fereastră unde utilizatorul poate să caute mai multe detalii despre un anumit server din țara de unde dorește informațiile

Se introduce la “Region Code” țara de unde se dorește informațiile . Dacă se doresc servere care sunt în producție sau servere care sunt de test se bifează corespunzător campurile “Find production systems” sau “Find other systems” . Se apasă butonul “Go”.

Serverele sunt afișate ca mai jos.

Butonul “Clear List” șterge tot rezultatul interogării de mai înainte pentru a pregăti fereastra de rezultat pentru o nouă interogare.

Butonul “Clear One Line” șterge linia selectată – poate fi folosit de oricâte ori are nevoie utilizatorul.

Dacă nu este bifat nici unul dintre câmpurile “Găsește sistemul de producție” sau “Găsește sisteme de test”, atunci pe ecran va apărea eroarea “Poate ar trebui să te consulți cu cineva cum se folosește această aplicație…” deoarece este obligatoriu ca măcar unul dintre aceste câmpuri să fie selectat.

Dacă pentru câmpul “Store ID” , unde este necesar să se introducă un număr, sunt introduse litere, pe ecran va fi afișată eroarea “I don’t accept shoes, handbags or flowers as Store.ID, Just plain numbers”. Aici se va introduce deci numărul serverului din țara respectivă .

Aplicația UserConnect poate exporta detaliile afișate intr-un fișier .csv pentru o documentație ulterioară a sistemelor.

Se va deschide o fereastră unde se va cere numele fișierului și locația unde va fi salvat, precum se va afișa și un anunț că fișierul a fost salvat cu succes.

Concluzii

O bază de date proiectată corespunzător furnizează acces la informații precise, actualizate. O proiectare corectă este esențială pentru atingerea scopurilor utilizării unei baze de date.

Unul dintre principiile unei bune proiectăr a bazei de date îl reprezintă importanța corectitudinii și caracterului complet al informațiilor. Dacă baza de date conține informații incorecte, orice rapoarte care extrag informații din baza de date vor conține, de asemenea, informații incorecte. Drept urmare, orice decizie luată bazată pe aceste rapoarte va fi greșit informată.

O proiectare bună a unei baze de date este, după cum urmează, una care:

Împarte informațiile în tabele pe baza subiectelor, pentru a reduce datele redundante.

Furnizează programului informațiile necesare pentru a asocia informațiile din tabele după necesități.

Asistă și asigură acuratețea și integritatea informațiilor.

Adaptează necesitățile de procesare a datelor și cele de raportare.

Aplicația “User connect” poate fi folosită de către administratorii de sistemîn cadrul unei rețele de calculatoare din afacerile mici și mari în orice domeniu. Rolul aplicației este de a ușura conectarea utilizatorului la o bază de date centrală sau la una locală, pentru a vizualiza detaliile de serverelor stocate în bazele de dateîn vederea configurărilor viitoare.

Bibliografie

1. http://ro.wikipedia.org/wiki/Microsoft_SQL_Server

2. http://www.tutorialeonline.net/ro/article/lucruri-pe-care-un-administrator-it-ar-trebui-sa-le-stie

3. http://www.referatele.com/referate/noi/informatica/baze-de-date227241923.php

4. http://www.microsoft.com/sqlserver/2008/en/us/editions.aspx

5. http://www.tutorialeonline.net/ro/article/lucruri-pe-care-un-administrator-it-ar-trebui-sa-le-stie#sthash.RkshYPRR.dpuf

6. http://www.referatele.com/referate/noi/informatica/baze-de-date227241923.php

7. http://biblioteca.regielive.ro/referate/ecologie/baze-de-date-in-visual-foxpro-248433.html

8. http://www.tutorialeonline.net/ro/article/lucruri-pe-care-un-administrator-it-ar-trebui-sa-le-stie-iii

9. http://www.warfare.ro/forum/index.php/topic/924-fox-pro/

10. http://labs.cs.upt.ro/labs/pbd/html

11. https://support.office.com/ro-ro/article/Noțiuni-de-bază-despre-proiectarea-bazelor-de-date

Anexă

Form1.cs

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Data.Sql;

using System.Data.SqlClient;

using System.IO;

using System.Text.RegularExpressions;

namespace ShowStoreInDB

{

publicpartialclassForm1 : Form

{

public Form1()

{

InitializeComponent();

textBox1.Text = "FFM";

textBox2.Text = "USIReader";

textBox4.Select();

}

privatebool ServerIsCorrect(string TillConfigFilePath)

{

string MposConfigContent = File.ReadAllText("c:\\config.xml");

string MposServerName=MposConfigContent.Substring

(MposConfigContent.IndexOf("Servername=")+12,12).ToLower();

if (File.ReadAllText(TillConfigFilePath).ToLower().Contains(MposServerName))

returntrue;

else

returnfalse;

}

privatevoid button1_Click(object sender, EventArgs e)

{

if (textBox4.Text.Length == 4)

{

// textBox4.Text = "BUK30MPS"+textBox4.Text;

}

else

if (textBox4.Text.Length < 12)

{

MessageBox.Show("Hostname invalid");

return;

}

SqlConnectionStringBuilder bu=newSqlConnectionStringBuilder();

bu.DataSource = textBox1.Text;

bu.IntegratedSecurity = false;

//Use USIReader / USIReader instead of mposusi:

bu.UserID = "USIReader";

//bu.UserID = "mposusi";

//string mppwd = "MposUsi_t0PS3cREt";

//…

bu.TrustServerCertificate = false;

if (textBox2.Text.Length > 0)

bu.UserID = textBox2.Text;

bu.InitialCatalog = "pos_usi";

//bu.Password = mppwd;

if (bu.UserID == "USIReader")

bu.Password = "USIReader";

if (textBox3.Text.Length > 0)

bu.Password = textBox3.Text;

SqlConnection conn = newSqlConnection(bu.ConnectionString);

try

{

conn.Open();

}

catch

{

MessageBox.Show("User greșit/parolă greșită, server-ul nu există sau nu există baza de date menționată", "Conexiunea nu a reușit");

return;

}

string Pattern = @"^[A-Z]{3}(11|30)[A-Z]{3}[0-9]{4}";

if (!Regex.IsMatch(textBox4.Text.ToUpper(), Pattern))

{

MessageBox.Show("Hostname-ul este invalid, reverificați", "Format invalid");

return;

}

string citystg = textBox4.Text.Substring(0, 3);

string saleslinestg = textBox4.Text.Substring(3, 2);

string srvrstg = textBox4.Text.Substring(5, 3);

string srvrnrstg = textBox4.Text.Substring(8);

string intstoreidstg = "";

string machprefix = citystg + saleslinestg;

DataSet ds = newDataSet("stores");

DataTable dt;

SqlCommand command;

SqlDataAdapter adapter = newSqlDataAdapter();

if (TheESL.isESL && srvrstg.ToUpper()=="ESL")

{

command = newSqlCommand

("SELECT storeid,externalstoreid,MyCityCode,IsProductive from [dbo].[stores] where storeid= (select mystoreid from [dbo].[machines] where mystoreid in (select storeid from [dbo].[stores] where mycitycode='"

+ citystg + "') and (MyType = 'ESL') and MachineID=" + srvrnrstg + " ) and mydistributionlinecode=" + saleslinestg, conn);

adapter.SelectCommand = command;

}

else

{

command = newSqlCommand

("SELECT storeid,externalstoreid,ejserver,MyCityCode,IsProductive from [dbo].[stores] where effectivecitycode like '"

+ citystg + "' and mydistributionlinecode=" + saleslinestg, conn);

adapter.SelectCommand = command;

}

SqlCommandBuilder cb = newSqlCommandBuilder(adapter);

adapter.Fill(ds, "stores");

dt = ds.Tables[0];

string regionMyCityCode = "";

string cmd2stg = "";

if (TheESL.isESL && srvrstg.ToUpper() == "ESL")

{

cmd2stg = "select count (*) from [dbo].[machines] where machineid="

+ srvrnrstg

//Only ESL, no MPOS

//+ "and (mytype like 'ESL') "

+ "and (mytype like 'ESL') "

+ "and mystoreid=";

}

else

{

cmd2stg = "select count (*) from [dbo].[machines] where machineid="

+ srvrnrstg

//Only MPOS, no ESL

//+ "and (mytype like 'pos' or mytype like 's3k' or mytype like 'pow' or mytype like 'sas') "

+ "and (mytype like 's3k' or mytype like 's3t') "

+ "and mystoreid=";

}

foreach (DataRow dr in dt.Rows)

{

SqlCommand cmd2 = newSqlCommand(cmd2stg + dr["storeid"].ToString(),conn);

if (Convert.ToInt32(cmd2.ExecuteScalar()) != 0)

{

intstoreidstg = dr["storeid"].ToString();

regionMyCityCode = dr["MyCityCode"].ToString();

}

}

if (intstoreidstg == "")

{

conn.Close();

MessageBox.Show("Sistemul nu a fost găsit");

return;

}

textBox5.Text = textBox4.Text+"\r\n\r\n";

foreach (DataRow dr in dt.Rows)

{

if (dr["storeid"].ToString() == intstoreidstg)

{

if (TheESL.isESL && srvrstg.ToUpper() == "ESL")

{

textBox5.Text += "ID Magazin: " + intstoreidstg

+ "\r\nNr. magazin: " + dr["externalstoreid"].ToString();

}

else

{

textBox5.Text += "ID Magazin: " + intstoreidstg

+ "\r\nNr. magazin: " + dr["externalstoreid"].ToString();

//+ "\r\nEJ server: " + dr["EJServer"].ToString();

}

if (dr["IsProductive"].ToString() == "False")

textBox5.Text += "\r\nProductiv: No";

else

{

textBox5.Text += "\r\nProductiv: Yes "; //, since " + dr["ProductiveSince"].ToString().Substring(0,10);

}

textBox5.Text += "\r\n\r\n";

}

}

//Find country:

string citycode=textBox4.Text.Substring(0,3).ToUpper();

ds = newDataSet("cities");

command = newSqlCommand("SELECT * from [dbo].[cities] where citycode like '"+regionMyCityCode+"'", conn);

adapter.SelectCommand = command;

cb = newSqlCommandBuilder(adapter);

adapter.Fill(ds, "cities");

dt = ds.Tables[0];

string regioncode="";

foreach (DataRow dr in dt.Rows)

{

regioncode = dr["MyRegionCode"].ToString();

}

textBox5.Text += "\r\nEchipamente:\r\n\r\n";

//( * =Installation requested)

DataSet dstypes = newDataSet("machinetypes");

command = newSqlCommand("SELECT * FROM [dbo].[machinetypes]", conn);

adapter.SelectCommand = command;

cb = newSqlCommandBuilder(adapter);

adapter.Fill(dstypes, "machinetypes");

DataTable dttypes = dstypes.Tables[0];

DataSet dsboards = newDataSet("managementboards");

command = newSqlCommand("SELECT machineuniqueid,ipaddress,MAC FROM [dbo].[managementboards]", conn);

adapter.SelectCommand = command;

cb = newSqlCommandBuilder(adapter);

adapter.Fill(dsboards, "managementboards");

DataTable dtboards = dsboards.Tables[0];

// MachineParams:

DataSet dsmachpars = newDataSet("machineparams");

command = newSqlCommand("SELECT * FROM [dbo].[machineparams]", conn);

adapter.SelectCommand = command;

cb = newSqlCommandBuilder(adapter);

adapter.Fill(dsmachpars, "machineparams");

DataTable dtmachpars = dsmachpars.Tables[0];

// WSGroups:

DataSet dsws = newDataSet("wsgroups");

command = newSqlCommand("SELECT * FROM [dbo].[wsgroups]", conn);

adapter.SelectCommand = command;

cb = newSqlCommandBuilder(adapter);

adapter.Fill(dsws, "wsgroups");

DataTable dtws = dsws.Tables[0];

ds = newDataSet("machines");

command = newSqlCommand("SELECT * from [dbo].[machines] where mystoreid=" + intstoreidstg + "order by machineid", conn);

adapter.SelectCommand = command;

cb = newSqlCommandBuilder(adapter);

adapter.Fill(ds, "machines");

dt = ds.Tables[0];

foreach (DataRow dr in dt.Rows)

{

string sIp = "".PadLeft(16);

string sMac = "".PadLeft(16);

string sIlo = "".PadLeft(16);

foreach (DataRow drt in dttypes.Rows)

{

if (drt["machinetypecode"].ToString().ToUpper() == dr["mytype"].ToString().ToUpper())

{

textBox5.Text += machprefix + drt["myclassificationcode"].ToString().ToLower() + dr["machineid"].ToString().PadLeft(4,'0');

sIp = dr["IPAddress"].ToString().PadRight(16);

sMac = dr["MAC"].ToString().PadRight(16);

if (Convert.ToBoolean(dr["RequestInstallation"]))

textBox5.Text += " *";

else

textBox5.Text += " ";

foreach (DataRow drboard in dtboards.Rows)

{

if (dr["uniqueid"].ToString() == drboard["machineuniqueid"].ToString())

{

sIlo = " ILO: " + drboard["IPAddress"].ToString() + " (" + drboard["MAC"].ToString() + ")";

}

}

textBox5.Text += sIp + sMac;

textBox5.Text += sIlo.PadRight(40)+dr["MyWsGroup"].ToString().PadRight(7);

foreach (DataRow drws in dtws.Rows)

{

if (dr["MyWsGroup"].ToString() == drws["GroupCode"].ToString())

{

textBox5.Text += drws["GroupName"].ToString() + " – " + drws["ApplicationType"].ToString() + " (" + drws["GroupRepresentative"].ToString() + ") ";

}

}

textBox5.Text += " ID: " + dr["UniqueID"].ToString();

textBox5.Text += " " + dr["RequestType"].ToString();

textBox5.Text += "\r\n";

//Machine parameters:

foreach (DataRow drmach in dtmachpars.Rows)

{

if (dr["uniqueid"].ToString() == drmach["uniqueid"].ToString())

{

textBox5.Text += " Param. " + drmach["Name"].ToString() + " = " + drmach["value"].ToString() + "\r\n";

}

}

}

}

}

//Country params:

if (TheESL.isESL && srvrstg.ToUpper() == "ESL")

{

}

else

{

textBox5.Text += "\r\n\r\nParametrii țării (" + regioncode + "):\r\n\r\n";

ds = newDataSet("regionparams");

command = newSqlCommand("SELECT * from [dbo].[regionparams] where myregioncode like '" + regioncode + "'", conn);

adapter.SelectCommand = command;

cb = newSqlCommandBuilder(adapter);

adapter.Fill(ds, "regionparams");

dt = ds.Tables[0];

foreach (DataRow dr in dt.Rows)

{

textBox5.Text += dr["Name"].ToString().PadRight(48) + " = " + dr["value"].ToString() + "\r\n";

}

//Store params:

textBox5.Text += "\r\n\r\nParametri per magazin:\r\n\r\n";

ds = newDataSet("storeparams");

command = newSqlCommand("SELECT * from [dbo].[storeparams] where uniqueid=" + intstoreidstg, conn);

adapter.SelectCommand = command;

cb = newSqlCommandBuilder(adapter);

adapter.Fill(ds, "storeparams");

dt = ds.Tables[0];

foreach (DataRow dr in dt.Rows)

{

textBox5.Text += dr["name"].ToString().PadRight(28) + " = " + dr["value"].ToString() + "\r\n";

}

}

conn.Close();

}

privatevoid button2_Click(object sender, EventArgs e)

{

Form2 sidFrm = newForm2();

sidFrm.UID="USIReader";

if (textBox2.Text.Length > 0)

sidFrm.UID = textBox2.Text;

sidFrm.UPWD = "USIReader";

if (textBox3.Text.Length > 0)

sidFrm.UPWD = textBox3.Text;

sidFrm.UDB = textBox1.Text;

sidFrm.ShowDialog();

if (sidFrm.URes != "") textBox4.Text = sidFrm.URes;

if (textBox4.Text.Length > 11)

button1_Click(sender, e);

}

privatevoid OnSizeChanged(object sender, EventArgs e)

{

int hor = this.Size.Width;

int ver = this.Size.Height;

textBox5.Width = hor – 32;

textBox5.Height = ver – 260;

}

privatevoid BtnGirls_Click(object sender, EventArgs e)

{

if (!Colors.IsGirl)

{

Colors.SaveColors(this.BackColor, button1.BackColor, textBox5.BackColor, textBox4.BackColor);

Colors.IsGirl = true;

BtnGirls.Text = "Schimba culoarea";

}

else

Colors.IsGirl=false;

this.BackColor = Colors.GetColorBkg();

textBox5.BackColor = Colors.GetColorLb();

textBox1.BackColor = Colors.GetColorBTb();

textBox2.BackColor = Colors.GetColorBTb();

textBox3.BackColor = Colors.GetColorBTb();

textBox4.BackColor = Colors.GetColorBTb();

button1.BackColor = Colors.GetColorBtn();

button2.BackColor = Colors.GetColorBtn();

BtnGirls.BackColor = Colors.GetColorBtn();

BtnGirls.Text = "Schimba culoarea";

}

privatevoid button3_Click(object sender, EventArgs e)

{

if (!TheESL.isESL)

{

button3.Text = "MPOS View";

TheESL.setESL(true);

}

else

{

button3.Text = "ESL View";

TheESL.setESL(false);

}

}

privatevoid textBox1_TextChanged(object sender, EventArgs e)

{

}

privatevoid textBox4_TextChanged(object sender, EventArgs e)

{

}

privatevoid Form1_Load(object sender, EventArgs e)

{

}

privatevoid textBox5_TextChanged(object sender, EventArgs e)

{

}

}

publicstaticclassTheESL

{

publicstaticbool isESL = false;

publicstaticvoid setESL(bool value)

{

isESL = value;

}

}

publicstaticclassColors

{

publicstaticColor CBkg = newColor();

publicstaticColor CBtn = newColor();

publicstaticColor CLb = newColor();

publicstaticColor CTb = newColor();

publicstaticbool IsGirl = false;

publicstaticvoid SaveColors(Color cbk, Color cbt, Color clb, Color ctb)

{

CBkg = cbk;

CBtn = cbt;

CLb = clb;

CTb = ctb;

}

publicstaticColor GetColorBkg()

{ if (IsGirl) returnColor.Pink; elsereturn CBkg; }

publicstaticColor GetColorBtn()

{ if (IsGirl) returnColor.Lavender; elsereturn CBtn; }

publicstaticColor GetColorLb()

{ if (IsGirl) returnColor.PaleTurquoise; elsereturn CLb; }

publicstaticColor GetColorBTb()

{ if (IsGirl) returnColor.Linen; elsereturn CTb; }

}

}

Form2.cs

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Data.Sql;

using System.Data.SqlClient;

using System.Threading;

using System.Diagnostics;

using System.IO;

namespace ShowStoreInDB

{

publicpartialclassForm2 : Form

{

publicstring UID = "";

publicstring UPWD = "";

publicstring UDB = "";

publicstring URes = "";

public Form2()

{

InitializeComponent();

radioButton1.Checked = true;

textBox1.Select();

}

privatevoid button1_Click(object sender, EventArgs e)

{

if (!checkBox1.Checked && !checkBox2.Checked)

{

if (Colors.IsGirl)

MessageBox.Show("Poate ar trebui să te consulți cu cineva cum se folosește această aplicație…", "Nu s-au selectat sisteme de producție sau de test");

else

MessageBox.Show("Selectați tipul sistemului");

return;

}

if (textBox2.Text.Length>0)

if (Colors.IsGirl)

{

try

{

int conv = Convert.ToInt32(textBox2.Text);

}

catch

{

MessageBox.Show("Nu accept nume, flori, bijuterii.. Doar numere.","IT");

return;

}

}

SqlConnectionStringBuilder bu = newSqlConnectionStringBuilder();

bu.DataSource = UDB;

bu.IntegratedSecurity = false;

bu.UserID = UID;

bu.TrustServerCertificate = false;

bu.InitialCatalog = "mpos_usi";

bu.Password = UPWD;

SqlConnection conn = newSqlConnection(bu.ConnectionString);

try

{

conn.Open();

}

catch

{

MessageBox.Show("User greșit/parolă greșită, server-ul nu există sau nu există baza de date menționată", "Conexiunea nu a reușit");

return;

}

DataSet ds = newDataSet("stores");

DataTable dt;

SqlDataAdapter adapter = newSqlDataAdapter();

if (textBox1.Text.Length != 3)

{

MessageBox.Show("Introduceți codul regiunii din 3 litere", "Informație lipsă");

return;

}

string sqlcmnd = "";

if (TheESL.isESL)

{

sqlcmnd = "SELECT StoreID, EffectiveCityCode, MyDistributionLineCode, StoreName, ExternalStoreID from [dbo].[stores] "

+ "where storeid in (Select mystoreid from [dbo].[machines] where mystoreid in "

+ "(SELECT StoreID from [dbo].[stores] where mycitycode in "

+ "(Select CityCode from [dbo].[Cities] where myregioncode ='"

+ textBox1.Text.ToUpper()

+ "')) and (MyType = 'ESL'))";

}

else

{

sqlcmnd = "SELECT StoreID, EffectiveCityCode, MyDistributionLineCode, StoreName, ExternalStoreID from [dbo].[stores] "

+ "where mycitycode in (Select CityCode from [dbo].[Cities] where myregioncode = '"

+ textBox1.Text.ToUpper()

+ "')";

}

if (textBox2.Text.Length > 0)

sqlcmnd += " AND ExternalStoreID = " + textBox2.Text;

SqlCommand command = newSqlCommand(sqlcmnd,conn);

adapter.SelectCommand = command;

SqlCommandBuilder cb = newSqlCommandBuilder(adapter);

try

{

adapter.Fill(ds, "stores");

}

catch (Exception exc)

{

MessageBox.Show(exc.Message);

return;

}

dt = ds.Tables[0];

string stg1 = "";

string stg2 = "";

foreach (DataRow dr in dt.Rows)

{

bool AddToList = true;

string cmd2stg = "";

if (TheESL.isESL)

{

cmd2stg = "SELECT MyType, MachineID from [dbo].[Machines] where MyType='esl' and mystoreid=" + dr["StoreId"].ToString();

}

else

{

cmd2stg = "SELECT MyType, MachineID from [dbo].[Machines] where (MyType='s3k' or MyType='sas' or MyType='pos' or MyType='pow' or MyType='esl') and mystoreid=" + dr["StoreId"].ToString();

}

SqlCommand cmd2 = newSqlCommand(cmd2stg, conn);

adapter.SelectCommand = cmd2;

SqlCommandBuilder cb2 = newSqlCommandBuilder(adapter);

DataSet dm = newDataSet("machines");

adapter.Fill(dm,"machines");

DataTable dt2 = dm.Tables[0];

// MPOS, SAS, MPC, MPW:

string stg3 = "";

foreach (DataRow dr2 in dt2.Rows)

{

if (TheESL.isESL)

{

if (dr2["MyType"].ToString().ToUpper() == "ESL")

{

stg3 = dr2["MachineId"].ToString();

while (stg3.Length < 4) stg3 = "0" + stg3;

stg3 = "ESL" + stg3;

}

}

else

{

if (dr2["MyType"].ToString().ToUpper() == "ESL")

AddToList = false;

if (dr2["MyType"].ToString().ToUpper() == "S3K")

{

stg3 = dr2["MachineId"].ToString();

while (stg3.Length < 4) stg3 = "0" + stg3;

stg3 = "MPS" + stg3;

}

}

}

if (!TheESL.isESL)

{

if (stg3 == "")

foreach (DataRow dr2 in dt2.Rows)

{

if (dr2["MyType"].ToString().ToUpper() == "SAS")

{

stg3 = dr2["MachineId"].ToString();

while (stg3.Length < 4) stg3 = "0" + stg3;

stg3 = "SAS" + stg3;

}

}

if (stg3 == "")

foreach (DataRow dr2 in dt2.Rows)

{

if (dr2["MyType"].ToString().ToUpper() == "POS")

{

stg3 = dr2["MachineId"].ToString();

while (stg3.Length < 4) stg3 = "0" + stg3;

stg3 = "MPC" + stg3;

}

}

if (stg3 == "")

foreach (DataRow dr2 in dt2.Rows)

{

if (dr2["MyType"].ToString().ToUpper() == "POW")

{

stg3 = dr2["MachineId"].ToString();

while (stg3.Length < 4) stg3 = "0" + stg3;

stg3 = "MPW" + stg3;

}

}

}

if (stg3 == "")

stg3 = "… ";

stg1 = "Store " + dr["ExternalStoreID"].ToString() + " – " + dr["EffectiveCityCode"].ToString()

+dr["MyDistributionLineCode"].ToString();

stg2 = " – " + dr["StoreName"].ToString().Replace("-", "/").Replace(";", "/").Replace(",", "/")

+ " (" + dr["StoreId"].ToString() + ")";

if (!checkBox1.Checked)

if (

(stg3.ToUpper().Contains("SAS0")) ||

(stg3.ToUpper().Contains("SAS1")) ||

(stg3.ToUpper().Contains("MPS0")) ||

(stg3.ToUpper().Contains("MPS1")))

AddToList=false;

if (!checkBox2.Checked)

if (

(stg3.ToUpper().Contains("SAS2")) ||

(stg3.ToUpper().Contains("SAS3")) ||

(stg3.ToUpper().Contains("SAS4")) ||

(stg3.ToUpper().Contains("SAS5")) ||

(stg3.ToUpper().Contains("SAS6")) ||

(stg3.ToUpper().Contains("SAS7")) ||

(stg3.ToUpper().Contains("SAS8")) ||

(stg3.ToUpper().Contains("SAS9")) ||

(stg3.ToUpper().Contains("MPS2")) ||

(stg3.ToUpper().Contains("MPS3")) ||

(stg3.ToUpper().Contains("MPS4")) ||

(stg3.ToUpper().Contains("MPS5")) ||

(stg3.ToUpper().Contains("MPS6")) ||

(stg3.ToUpper().Contains("MPS7")) ||

(stg3.ToUpper().Contains("MPS8")) ||

(stg3.ToUpper().Contains("MPS9")))

AddToList=false;

if (AddToList)

listBox1.Items.Add(stg1+stg3+stg2);

}

conn.Close();

this.AcceptButton = button1;

}

privatevoid button2_Click(object sender, EventArgs e)

{

listBox1.Items.Clear();

}

privatevoid listBox1_DoubleClick(object sender, EventArgs e)

{

URes = listBox1.SelectedItem.ToString();

URes = URes.Remove(0, URes.IndexOf("-") + 2);

URes = URes.Remove(URes.IndexOf(" "));

if (URes.Length < 5) URes = "";

this.Close();

}

privatevoid button3_Click(object sender, EventArgs e)

{

}

privatevoid listBox1_SelectedIndexChanged(object sender, EventArgs e)

{

URes = listBox1.SelectedItem.ToString();

URes = URes.Remove(0, URes.IndexOf("-") + 2);

URes = URes.Remove(URes.IndexOf(" "));

if (URes.Length < 5) URes = "";

}

privatevoid button4_Click(object sender, EventArgs e)

{

if (listBox1.SelectedIndices.Count==0)

{

MessageBox.Show("Nici un magazin selectat.");

return;

}

if (listBox1.Items.Count < 2)

{

MessageBox.Show("Nu folosiți acest buton decât dacă sunt cel puțin 2 magazine în listă");

return;

}

int i = listBox1.SelectedIndex;

if (i>0)

listBox1.SetSelected(0, true);

else

listBox1.SetSelected(1, true);

listBox1.Items.RemoveAt(i);

}

privatevoid button6_Click(object sender, EventArgs e)

{

if (listBox1.SelectedIndices.Count == 0)

{

MessageBox.Show("Nici un magazin selectat.");

return;

}

try {

Process.Start("mstsc.exe", "/v " + URes);

}

catch

{

MessageBox.Show("Remote desktop nu a putut fi inițializat.");

}

}

privatevoid button7_Click(object sender, EventArgs e)

{

if (listBox1.SelectedIndices.Count == 0)

{

MessageBox.Show("Nici un magazin selectat.");

return;

}

try {

Process.Start("mstsc.exe", "/v " + URes.ToUpper().Replace("11MPS","11SAS"));

}

catch {

MessageBox.Show("Remote desktop nu a putut fi inițializat.");

}

}

privatevoid button5_Click(object sender, EventArgs e)

{

SaveFileDialog saveFileDialog1 = newSaveFileDialog();

saveFileDialog1.Filter = "csv files (*.csv)|*.csv|All files (*.*)|*.*";

saveFileDialog1.FilterIndex = 1;

saveFileDialog1.RestoreDirectory = true;

Stream checkStream;

if (saveFileDialog1.ShowDialog() == DialogResult.OK)

{

if ((checkStream = saveFileDialog1.OpenFile()) != null)

{

string csvseparator = ";";

if (radioButton2.Checked)

csvseparator = ",";

checkStream.Close();

string oneLine="Store;Server name;Store name;USI ID\r";

File.WriteAllText(saveFileDialog1.FileName,oneLine);

int numItems=listBox1.Items.Count;

for (int i=0;i<numItems;i++)

{

oneLine = listBox1.Items[i].ToString().Replace("Store ","").Replace(" – ", csvseparator);

int bracketPos = oneLine.LastIndexOf("(");

oneLine = oneLine.Remove(oneLine.Length – 1).Remove(bracketPos-1,2).Insert(bracketPos-1,csvseparator);

File.AppendAllText(saveFileDialog1.FileName, oneLine+"\r");

} }

}

MessageBox.Show(saveFileDialog1.FileName + " a fost salvat.", "File export", MessageBoxButtons.OK, MessageBoxIcon.Information);

try

{

Process.Start(saveFileDialog1.FileName);

}

catch {

}

}

privatevoid Form2_Load(object sender, EventArgs e)

{

button1.BackColor = Colors.GetColorBtn();

this.BackColor = Colors.GetColorBkg();

listBox1.BackColor = Colors.GetColorLb();

textBox1.BackColor = Colors.GetColorBTb();

textBox2.BackColor = Colors.GetColorBTb();

button2.BackColor = Colors.GetColorBtn();

button3.BackColor = Colors.GetColorBtn();

button4.BackColor = Colors.GetColorBtn();

button5.BackColor = Colors.GetColorBtn();

if (!TheESL.isESL)

{

button6.BackColor = Colors.GetColorBtn();

button7.BackColor = Colors.GetColorBtn();

button8.Visible = false;

}

else {

button6.Visible = false;

button7.Visible = false;

button8.BackColor = Colors.GetColorBtn();

}

}

privatevoid button8_Click(object sender, EventArgs e)

{

if (listBox1.SelectedIndices.Count == 0)

{

MessageBox.Show("Nici un magazin selectat.");

return;

}

try

{

Process.Start("mstsc.exe", "/v " + URes);

}

catch

{

MessageBox.Show("Remote desktop nu a putut fi inițializat.");

}

}

privatevoid textBox1_TextChanged(object sender, EventArgs e)

{

}

}

}

Similar Posts