Kako da dodam atribut entitetu a da ne dodajem kolonu u tabelu?

Skoro sam čuo pitanje: Treba mi da dodam još par atributa na Kupcima. Jel da dodam te kolone u u tabelu Kupac ili da dodam novu tabelu za takve atribute i da u nju dodajem kolone?

Da li ovakve zahteve uvek rešavate na ovakav način? Mislim da bi većina vas odgovorila sa DA pošto smo svi mi robovi nekih navika.

Hajde da razmotrimo šta dodavanje kolone ili tabele sa kolonama, pogotovu kad je sistem već na produkciji, ima obično za posledicu. Prvo, to je izmena koja podrazumeva izmenu fizičkog modela baze. Takva izmena zahteva i izmenu view-ova ili stored procedura na bazi, ako je tako definisana arhitektura sistema ili izmenu na nivou nekog ORM-a, recimo Entity Framework modela. Zatim, to podrazumeva i izmenu svih servisa i objekata koji rade sa Kupcima, izmenu front end-a i  izmenu i dodavanje automatskih testova. Naravno treba uzeti u obzir i prateći reporting sistem ako je takav predviđen. Sve ovo naravno podrazumeva i ceo ciklus potrebnih aktivnosti da  bi se došlo do postavljanja nove verzije sistema na produkciono okruženje. Nisam siguran da sam sve pobrojao ali mislim da je i ovo dovoljno da bi se shvatilo da dodavanje par kolona znači da mnogi debelo treba da se oznoje da bi se par gore pomenutih  kolona pojavilo na front end-u na produkciji.

Da li možda postoji i neki drugi način? Naravno, najidealnije bi bilo ako ne bi morali ništa od prethodno pomenutog da uradimo. Da li je to moguće?

Rešenje je jednostavno. Potrebno je, u toku razvoja sistema, predvideti i kreirati jednu tabelu, pored tabele Kupci, koja će, pored kolone sa klasterovanim indeksom imati još samo tri kolone. Te tri kolone nove tabele su [Kupac_ID], koja je spoljnji ključ prema tabeli Kupac, [Naziv_promenjive], [Vrednost_promenjive]:

CREATE TABLE [Kupac_Atributi] (

[Kupac_Atribut_ID] int identity(1, 1) primary key

,[Kupac_ID] int

,[Naziv_promenjive] nvarchar(50)

,[Vrednost_promenjive] nvarchar(5)

)

Kreiranjem ovakve tabele dobili smo mogućnost da svaki put, kad je potrebno dodati neki novi atribut Kupca, treba samo dodati novi red u tu tabelu:

INSERT INTO [Kupac_Atributi]

VALUES (1,'Promenjiva_1',12345)

,(2,'Promenjiva_1',23456)

,(3,'Promenjiva_1',45678)

,(4,'Promenjiva_1',57823)

,(1,'Promenjiva_2',11111)

,(2,'Promenjiva_2',34304)

,(3,’Promenjiva_2′,12344)

To znači da nam za dodavanje novog atributa na Kupcu nije potrebno ništa od prethodno pobrojanog počev od dodavanja nove kolone na tabelu Kupac. To takođe znači da dobijamo i mogućnost da svaki kupac ili grupe kupaca, imaju različite atribute. Na front end-u ovakve podatke možemo prikazivati ili u txt box-u, gridu… kao više redova sa atributima Kupca i njihovim vrednostima:

Dodavanje atributa na entitete 1

Atributi i njihove vrednosti kao redovi

E sad, šta ako te podatke želimo da prikažemo na front end-u u kolonama, a ne redovima, zajedno sa ostalim podacima Kupaca, da ih prikažemo u tabeli na report-u, ili da damo mogućnost eksporta svih podataka o kupcima u Excel? Znači, pitanje koje se postavlja je: kako te redove sa dodatnim atributima Kupca da pretvorimo u kolone? To ćemo uraditi tako što ćemo kreirati stored proceduru:

CREATE PROCEDURE [dbo].[sp_VratiRedoveKaoKolone]

AS

BEGIN

DECLARE @SQL NVARCHAR(max)

DECLARE @Naziv_promenjive nvarchar(250)

set @Naziv_promenjive = ''

DECLARE db_cursor CURSOR FOR

SELECT [Naziv_promenjive]

FROM [Kupac_Atributi]

group by [Naziv_promenjive]

OPEN db_cursor

FETCH NEXT FROM db_cursor INTO @Naziv_promenjive

WHILE @@FETCH_STATUS = 0

BEGIN

SET @SQL = COALESCE(@Sql + ', ', '') + @Naziv_promenjive;

FETCH NEXT FROM db_cursor INTO @Naziv_promenjive

END

CLOSE db_cursor

DEALLOCATE db_cursor

SET @SQL = N';WITH CTE AS (
SELECT [Kupac_ID], [Vrednost_promenjive], [Naziv_promenjive]
FROM   [Kupac_Atributi]
)

SELECT *
FROM   CTE
PIVOT (MAX([Vrednost_promenjive]) FOR [Naziv_promenjive] IN (' + @SQL + N')) pvt';

EXECUTE (@SQL);

END

Izvršavanjem ove stored procedure dobijamo redove kao kolone:

Atributi i njihove vrednosti kao kolone

Atributi i njihove vrednosti kao kolone

Ako je potrebno voditi računa o tipu podataka u koloni [Vrednost_promenjive] onda na pomenutu tabelu treba dodati i kolonu [Tip_promenjive] i iskoristiti je u stored proceduri ili u logici koja vraća podatke za front end, report, eksport podataka…

Naravno, umesto pomenutih kolona, u tabeli sa atributuma Kupca, je moguće koristiti samo jednu kolonu sa XML tipom podataka. Koje god rešenje da izaberete, isplatiće se.

Leave a Reply

%d bloggers like this: