Cum funcționează
Tiparul canonic e la tabelul Carti. Cerința c) introduce ceva nou şi
important: o coloană calculată.
c) Calcul direct în SELECT
Până acum, calculele apăreau doar în UPDATE. Aici preţul compensat nu se stochează — se
calculează la afişare:
SELECT Denumire, Pret * (1 - Compensare / 100.0) AS Pret_de_plata
Tabelul rămâne neatins; doar rezultatul interogării conţine coloana nouă. E diferenţa esenţială
dintre SELECT (citeşte şi afişează) şi UPDATE (modifică datele).
AS Pret_de_plata dă un nume coloanei rezultate. Fără el, antetul ar fi întreaga expresie de calcul.
Capcana: Compensare / 100 dă zero
Aceasta e cea mai importantă greşeală din problemă, şi e invizibilă — nu dă nicio eroare.
Compensare e declarat întreg, iar 100 e tot întreg. În SQL, împărţirea între doi întregi e
împărţire întreagă:
5 / 100 = 0 (nu 0.05)
30 / 100 = 0 (nu 0.30)
Cu 0, formula devine Pret * (1 - 0) = Pret, deci toate preţurile rămân neschimbate şi
compensarea pare că n-a funcţionat. Rezultatul arată plauzibil, ceea ce face greşeala greu de
observat.
Soluţia: scrie 100.0, cu zecimală. Un singur operand real forţează împărţirea reală:
Compensare / 100.0 -- 5 / 100.0 = 0.05
E aceeaşi capcană ca la (double) în C++ — vezi
ordonarea fracţiilor.
Alternativă care evită problema: Pret * (100 - Compensare) / 100.0. Scăderea se face între
întregi, iar împărţirea o singură dată, la final.
Pentru Eurovita: 29.80 * (1 - 0.05) = 28.31. Pentru Coldrex: 24 * 0.70 = 16.80.
d) Ştergerea celor necompensate
WHERE Compensare = 0 elimină Cetebe plus şi Nurofen.
Atenţie: 0 nu e acelaşi lucru cu NULL. Aici zero e o valoare reală şi cunoscută — „nu se
compensează deloc" — nu o informaţie lipsă. Vezi
tabelul Clienti pentru diferenţă.
Greșeli frecvente
Compensare / 100 fără zecimală — rezultatul e 0 şi compensarea nu se aplică. Cea mai
frecventă şi cea mai greu de observat.
- Modificarea tabelului cu
UPDATE — enunțul cere doar afişarea, nu schimbarea preţurilor.
Pret * Compensare / 100.0 — calculează cât se scade, nu cât rămâne de plată.
AS uitat — coloana rezultată are un antet ilizibil.
WHERE Compensare IS NULL la d) — valoarea căutată e 0, nu absenţa ei.
ORDER BY Cod_medicament — enunțul cere alfabetic după denumire.