Mecanisme de Administrare a Datelor In Sistemele de Gestiune a Bazelor de Date
I. Introducere
Sisteme de gestiune a bazelor de date
Clasificarea sistemelor de gestiune de baze de date
II. Microsoft SQL Server
MSSQL Server
Protocoale, Porturi, Servicii
Editii MSSQL 2008
Instalarea Microsoft SQL Server 2008 R2 Express Edition
Instalarea instanței denumite – WEB01\SQLEXPRESS
Instalarea instanței implicite – WEB01
T-SQL (Transact-SQL)
Regula ACID
Locking
Blocking
Deadlock
Comenzi SQL – Tipuri și clasificare
Operatori logici
Proceduri stocate
Proceduri stocate parametrizate
Securitatea procedurilor stocate
Logins
Principals and permissions
Server roles
Database roles
Principals
Listare “logins” și “server roles”
Operații “logins”
Proceduri stocate: sp_addsrvrolemember, sp_dropsrvrolemember
Vizualizarea, modificarea și ștergerea unui login
Alocarea si revocarea permisiunilor unui login
III. Aplicația “User Connect”
Aplicația “User Connect” – Descriere și rol
Funcționalitate
Concluzii
Bibliografie
I . INTRODUCERE
Sistemul de Gestiune a Bazelor de Date (SGBD) prezintă sisteme informatice (soft) specializate în stocarea și prelucrarea unui volum mare de date. Un Sistem de Gestiune a Bazelor de Date (eng. DBMS – Database management system), este un set complex de programe ce permite organizarea, păstrarea, extragerea datelor din bazele de date. SGBD-urile utilizează anumite modele conceptuale pentru a putea gestiona datele: ierarhic, rețea, relațional, obiectual și obiectualrelațional.
Termenul "baza 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 (soft) specializate in stocarea si 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, alături de cel secvențial, acesta având ca efect imediat o creștere spectaculoasă a vitezei de acces la date; separarea nivelului logic de cel fizic, realizând astfel o independență logică a datelor. În această etapă se dezvoltă 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 cât mai mari de memorare și viteze cât mai mari de accesare a datelor memorate în bazele de date (discul optic, CD-urile, casetele magnetice 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 utilizeaza 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 astfel o relație, care asigură consultarea înregistrărilor din colecțiile de date de sus în jos și de la stânga spre dreapta (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 exceptia colectiei de date radacina), 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 intre 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 multimi numite domenii (Di), n fiind gradul relatiei. 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 (Marin Fotache – Proiectarea bazelor de date).
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 dă 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. Mai tarziu 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 cu extensia:
.mdf – întâlnite și sub denumirea de primary files sau main files. Acest fișier găzduiește obiectele unei baze de date (tabele, proceduri stocate, declanșatori, etc.). O bază de date poate să aibă maximum un fișier .mdf.
.ndf – secondary database file. În principal .ndf-ul 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. O bază de date poate avea zero sau mai multe fișiere .ndf.
.ldf – transaction log files – acest fișier va păstra un istoric al operațiunilor efectuate asupra datelor bazei de date.
Protocoale
Shared Memory: este cel mai simplist protocol de comunicație cu MSSQL (nici 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 este găzduită pe aceeași mașină pe care este găzduit și SGBD-ul. Î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, etc. În cazul LAN-urilor, diferențele dintre Named Pipes și TCP/IP sunt insesizabile, 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 rare cazurile în care este necesar a 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 (eng. default instance) sau instanțe cărora le-a fost alocat un nume (eng. named instance, în română am găsit formularea instanță denumită). Pe un server putem avea cel mult o instanță implicită și zero sau mai multe instanțe denumite.
OK, deci în cazul în care pe un server instalăm mai multe instanțe MSSQL, avem două posibilități:
pentru fiecare instanță în parte să alocăm porturi statice;
să lăsăm 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 putem 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 pe rețea, astfel încât să informeze clienții de portul alocat unei instanțe denumite.
Doar instanțele denumite (eng. 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ă avem de-a face cu o singură instanță implictă, putem renunța la serviciul SQL Server Browser (implicit instanța default este configurată a folosi TCP 1433).
Servicii MSSQL
Pe lângă rolul de SGBD, 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ă la momentul scrierii acestui articol 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);
(exemplele din cadrul acestei lucrări sunt realizate pe baza unei instanțe MSSQL Express)
Maximum Capacity Specifications for SQL Server 2008
Instrumente necesare:
SQLCMD – este utilitarul linie de comandă prin intermediul căruia se pot efectua diferite operații cu MSSQL (permite apelarea comenzilor SQL, execuția scripturilor, etc.). SQLCMD este utilitarul introdus odată cu Microsoft SQL Server 2005 și este succesorul OSQL (utilitar cu funcții asemănătoare apărut odată cu Microsoft SQL Server 2000). Se poate folosi și OSQL în cazul MSSQL Server 2005, MSSQL Server 2008, doar că 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 cuburilor OLAP, data mining, 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 configurata instanța ca fiind instanță implicită – WEB01. În prezentul articol WEB01 este denumirea NETBIOS a mașinii pe care se efectuează instalarea. Instalarea se va efectua pe baza kitului de instalare Microsoft SQL Server 2008 R2 RTM – Express with Management Tools).
Instalarea Microsoft SQL Server 2008 R2 necesită existența:
Microsoft .NET Framwework 3.5 SP1;
Microsoft Windows Installer 4.5;
Microsoft Windows PowerShell;
Instalarea instanței denumite – WEB01\SQLEXPRESS
În etapa de instalare vor fi selectate doar componentele strict necesare:
Database Engine Services;
Management Tools – Basic;
SQL Client Conectivity SDK;
Implicit (în cazul edițiilor EXPRESS), în etapa de instalare opțiunea implicită este cea de instalare a instanțelor denumite (eng. named instances).
În această etapă de instalare se pot configura conturile utilizator sub care serviciile windows asociate instanței MSSQL vor fi pornite. Se lasa valorile implicite și se trece la pasul următor.
Implicit, în etapa de instalare, modul de autentificare la o instanță MSSQL este Windows authentication mode. Asta înseamnă că autentificarea se va realiza pe baza unui cont utilizator Windows, iar sistemul de operare va fi cel care va confirma identitatea userului. În cazul Windows authentication mode, instanța MSSQL nu va cere nici o parolă și nici nu va efectua verificări asupra identității. Recomandat ar fi ca instanțele MSSQL să fie configurate a folosi doar Windows authentication mode deoarece:
acest mod de autentificare se folosește de protocolul Kerberos (proces de autentificare securizat);
pe baza unui singur cont utilizator poate fi alocat accesul la diferite resurse (de asemenea, blocarea acelui cont utilizator va presupune și blocarea accesului la toate resursele unde s-a alocat acces);
pot fi impuse în mod centralizat politici privind complexitatea, durata de valabilitate a parolelor;
în cazul aplicațiilor, nu este necesară salvarea în clar a userului și a parolei de acces (atât timp cât aplicația este executată sub credențialele contului utilizator pentru care s-a alocat acces explicit în instanța MSSQL);
etc.
SQL Server authentication mode, presupune:
ca autentificarea să fie realizată de către instanța MSSQL;
păstrarea userului și parolei de acces în cadrul instanței MSSQL (deci nu există nici o legătură între conturile Windows și userii MSSQL);
furnizarea userului și a parolei de fiecare dată când se realizează autentificarea la instanța MSSQL;
etc;
Indiferent de opțiunea aleasă în etapa de instalare (Windows authentication mode sau Mixed mode), pentru fiecare instanță MSSQL instalată va fi realizat contul MSSQL sa. În cazul Windows authentication mode, userul va fi creat, dar contul nu va fi activ (deci, nu va fi posibilă conectarea la instanța MSSQL pe baza acestui user). În cazul Mixed mode, userul va fi creat, iar imediat după instalare, va fi posibilă conectarea pe baza contului SQL.
În cadrul aceluiași pas de instalare (Database Engine Configuration), în cadrul de pagină Data Directories puteți să configurați:
locația pe disc unde va fi instalată instanța MSSQL;
directoarele implicite ce vor găzdui bazele de date;
locația implicită de găzduire a backup-urilor.
Se recomandă ca atât instalarea instanței MSSQL cât și găzduirea bazelor de date să fie făcute pe volume diferite de cel pe care este găzduit sistemul de operare. (în cazul acestui articol, am să păstrez configurația implicită, dat fiind faptul că instanțele MSSQL nu vor fi publicate în mediul de producție)
Instalarea instanței implicite – WEB01
La pasul “Installation type” se selectează “New installation or add shared fetures” .
La pasul “Instance configuration” se selectează “Default instance” – de asemenea tot aici se menționează calea unde se va instala instanța respectivă – calea default este :
C:\Program Files\Microsoft SQL Server .
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, 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ă = o parte a unui proces 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 tip “totul sau nimic” – făcînduse toți pașii sau nici unul
Consistency – asigură faptul că datele sunt valide atât înainte cât și după tranzacție. Integritatea datelor trebuie păstrată și structura internă a datelor trebuie să fie întro 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ă vadă datele altei tranzacții ce este într-o stare inter mediară. 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 este executată imediat
Exemplu: două comenzi INSERT pentru debitarea/creditarea unui cont
Exemplu: ștergerea datelor dintr-o tabelă nu poate fi anulată
Implicit – acest mod este activat cu comanda:
SET IMPLICIT_TRANSACTIONS ON
Pentru a-l dezactiva :
SET IMPLICIT_TRANSACTIONS OFF
Cu acest mod 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 SGBD 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ță :
– un user încearcă să citească date modificate de altul
– un user incearcă să modifice date pe care altul le citește
– un user incearcă să modifice date pe care altul încearcă să le modifice
Lock – sunt plasate asupra resurselor SQL Server
Lock mode = Modul în care este blocată o resursă
Shared lock – plasat în timpul interogărilor readonly, 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. 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 tablă sau baza 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 8KB
– 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.
Pe o resursă care are un exclusive lock , nu se pot pune alte lock-uri
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 se referă la 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 – 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 BD
2. Non-repeatable reads – 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 – 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 – 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 ce alte tranzacții vor să citească sau să modifice
Blocările pe termen scurt sunt de regulă OK ș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
Motive 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ă input de la user în timp de conexiunea rămâne deschisă
c ) Aplicațiile folosesc tranzacții 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 îmbunătăți concurența)
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:
– Sesiunea 1 are un lock pe resurse ce trebuie modificate de Sesiunea 2
– Sesiunea 2 are un lock pe resurse ce trebuie modificate de Sesiunea 1
– 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: Sesiunea 1 actualizează Customers și apoi Orders, iar Sesiunea 2 actualizează Orders și apoi Customers
– 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ă ( numeric-priority – valori de la -10 la 10 ) .
COMENZI SQL
SQL Server folosește 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 tipul valorilor pentru coloana respectivă (tipuri de date MSMSQL)
SELECT – Cautare informații in BD
Clasificare comenzi SQL
Grup DML(Data Manipulation Language)
UPDATE – Modificare conținut înregistrări dintr-o tabelă
INSERT INTO – Adăugare inregistrari intr-o tabelă
DELETE FROM – Ștergere înregistrări dintr-o tabelă
Grup DDL (Data Definition Language)
CREATE obiect – Creare structură tabelă, index
ALTER obiect – Modificare caracteristici tabelă,index,sesiune,user,roll,..
DROP obiect – Ștergere tabelă,index,vedere,trigger,secvența,..
RENAME obiect – Redenumire tabelă sau viewlayer
TRUNCATE TABLE – Șterge toate înregistrarile dintr-o tabelă
Grup Control tranzacții
COMMIT – Confirma terminare tranzactie
ROLLBACK – Reface toate modificarile BD de la inceputul tranzactiei (ultimul COMMIT)
SAVEPOINT – Creeaza un punct de reluare in tranzactie
Grup DCL (Data Control language)
GRANT – Acorda drepturi pentru un user
REVOKE – Retrage drepturi de la un user
Descriere comenzi: O comanda se poate scrie pe mai multe randuri si se termina cu ;
CREATE TABLE tabela (col1 tip1, col2 tip2,…..); – definire campuri tabela
CREATE TABLE tabela AS SELECT * FROM tab2; – copiere alta tabela
CREATE INDEX nume_index ON tabela(col1,col2,..); – creare index pentru o tabela
CREATE INDEX inume ON pers (Nume); – creare index INUME pentru tabela PERS
ALTER TABLE tabela ADD (col1 tip1,col2 tip2,..);
ALTER TABLE tabela MODIFY (col1 tip1,col2 tip2,..);
ALTER TABLE tabela DROP COLUMN col1,col2;
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 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
Avantaje:
– ajută la centralizarea codului SQL în data tier. Aplicațiile ce includ cod SQL ad-hoc sunt greu de depanat și întreținut.
– reduc traficul pe rețea pentru interogări ad-hoc formate din multe linii. (e mai 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ă – 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 afișarea/transmiterea 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 : Input – de intrare și Output – de ieșire 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 si 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
– stabilirea contextului de securitate pentru PS
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: crearea / ștergerea 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, etc. De reținut faptul că 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 adăuga / elimina linked servers, administra replicările, precum și de a executa anumite proceduri stocate în sistem. Linked servers – 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 adăuga și șterge login-urile respectivei baze de date (dar fără posibilitatea de a asigna permisiuni).
db_backupoperator: membrii acestui rol pot realiza copii de siguranță asupra respectivei baze de date (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 (adăugare/modificare/ștergere) asupra oricărui tabel din respectiva bază de date.
db_ddladmin: membrii acestui rol pot executa comenzi DDL (data definition language) asupra respectivei baze de date. DDL – creare/modificare/ștergere: tabel, index, trigger, stored procedure, function, 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 (adăugare/modificare/ștergere) 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 adăuga/șterge login-uri). Atat 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:
windows domain user accounts;
windows local user accounts;
windows domain groups;
windows local groups;
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 – pe baza parametrului @srvrolename pot fi făcute filtrări
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;
cu schimbare parolă la prima autentificare;
DEFAULT_LANGUAGE = us_english;
aplicare politicii de securitate referitoare la schimbarea parolei, complexitate, etc.
Cum poate fi facut login-ul “USIReader” membru al rolului sysadmin – se poate folosi procedura stocata sp_addsrvrolemember.
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 tabelaStores;
doar dreptul de citire (selecție) asupra tabeleiCities;
doar dreptul de citire (selecție) asupra tabeleiCountries;
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 înorice 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 intre 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
http://biblioteca.regielive.ro/referate/ecologie/baze-de-date-in-visual-foxpro-248433.html
7. http://www.tutorialeonline.net/ro/article/lucruri-pe-care-un-administrator-it-ar-trebui-sa-le-stie-iii
8. http://www.warfare.ro/forum/index.php/topic/924-fox-pro/
9. http://labs.cs.upt.ro/labs/pbd/html
10. 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)
{
}
}
}
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
http://biblioteca.regielive.ro/referate/ecologie/baze-de-date-in-visual-foxpro-248433.html
7. http://www.tutorialeonline.net/ro/article/lucruri-pe-care-un-administrator-it-ar-trebui-sa-le-stie-iii
8. http://www.warfare.ro/forum/index.php/topic/924-fox-pro/
9. http://labs.cs.upt.ro/labs/pbd/html
10. 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)
{
}
}
}
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Mecanisme de Administrare a Datelor In Sistemele de Gestiune a Bazelor de Date (ID: 150018)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
