Hasznos kategória bejegyzései

Kezdjük a végén?!

Az adatok valahol megszületnek, ami általában egy alkalmazás szerver szokott lenni. Amikor adatbázisba készülünk letárolni, akkor hosszú vándorútra indulnak a születési helyüktől az adatbázisig. Vannak, amik “messzebbről” indulnak és hamarabb érkeznek meg és van fordítva is. Itt már lehet sejteni, hogy az adatok nem feltétlen abban a(z) (idő)sorrendben kerülnek be az adatbázisba, ahogy létrejönnek. Az esetek többségében ez nem is probléma, mert nem lényeges, viszont van, amikor a legfontosabb tényezővé válik. Ezzel az esettel már többféle formában is találkoztam, most egy egyszerűbb példán keresztül mutatnám be.

 

Legyen egy felhasznalok táblánk, ami az alábbiként néz ki és azt rögzíti, hogy ki és mit csinált a weboldalon:

id: sorszam

felhasznalo: akire vonatkozik ez a sor

tevekenyseg: amit csinált a felhasználó

tevekenyseg_kezdete: amikor elkezdte a tevékenységét a felhasználó az alkalmazás szerint

sor_keletkezesi_ideje: amikor az adatbázisba került a sor

 

Az elvárt működés, hogy belép a felhasználó, végez tevékenységeket, végül kilép.

Nézzünk egy képet, ami erre rácáfol:

01_order

 

A fenti képen tisztán látszik, hogy Kati utolsó három sorának a “tevekenyseg_kezdete” mező ugyanazt a dátumot tartalmazza (aminek nem kell így legyen, hogy a probléma valós maradjon), viszont a “kilépés” tevékenysége (id = 5) hamarabb érkezett be az adatbázisba, mint a “negyedik tevékenység” sora (id = 6).

Most, hogy ismerjük a problémát már bármilyen mesét köré lehet szőni, hogy ez miért rossz. A mienk legyen az, hogy, ha a felhasználó kilép, akkor elindul egy folyamat, ami minden tevékenységéért jóváír neki x összeget. Itt meg kimaradna egy tevékenység.

Ha ezt még nem ismertük, akkor jó ha tudunk róla. Viszont rossz hír, hogy nincs általános megoldás ahány eset annyi féle.

 

 

SQL Server Linuxon

Juhúú, megjelent az SQL Server Linuxon. Install segédlet itt: https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup

Mint látszik jelenleg 3 platformon érhető el:

  • Red Hat Enterprise Linux
  • Ubuntu
  • Docker Engine

Én Ubuntura raktam fel teszt jelleggel. Ebben a postban néhány fontos konfigurációs  beállítást mutatok be, hogy az SQL Server ne nyűg, hanem használható társ legyen.

Telepítás után rendelkezésre áll az sqlcmd konzol. Gyorsan felejtsük el, keressünk valami használható toolt helyette. Ilyen pl.: a Heidi SQL. Én windows alól, távolról kapcsolódtam az Ubuntura telepített szerverhez SSMS-el. Szerintem ez a legjobb tool a kezeléséhez.

Csatlakozzunk az SQL szerverhez, példa itt: https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-connect-and-query-sqlcmd

 

Most állítsuk be, hogy ne zabálja ki alólunk a memóriát a szerver:

use master
go

EXEC sys.sp_configure N'show advanced options', N'1'  RECONFIGURE WITH OVERRIDE
GO
-- Min memory
EXEC sys.sp_configure N'min server memory (MB)', N'512'
GO
-- Max memory
EXEC sys.sp_configure N'max server memory (MB)', N'1024'
GO
-- Optimize memory for ad hoc queries
EXEC sys.sp_configure N'optimize for ad hoc workloads', N'1'
GO
RECONFIGURE WITH OVERRIDE
GO
EXEC sys.sp_configure N'show advanced options', N'0'  RECONFIGURE WITH OVERRIDE
GO

--Nézzük meg, hogy sikerült e:
select
name,
minimum,
value_in_use
from sys.configurations
where name like '%server memory%'
or name like '%optimize for ad hoc workloads%'
go

 

02_memory_config

 

Állítsuk be a modell adatbázist SIMPLE recovery-re. Ez azért fontos, mert az újonnan létrehozott adatbázisok ennek az adatbázisnak a mintájára fognak létrejönni. Aki nem tudja, hogy ez mire való, annak érdemes átállítani. A lényege, hogy az adatbázisok nem fogják felzabálni a diszket.

 

-- Deault recovery modell
ALTER DATABASE [model] SET RECOVERY SIMPLE WITH NO_WAIT
GO

 

Ha esetleg valami baj van a szerverrel, azt az error logban lehet megnézni, nekem default ide települt: var/opt/mssql/log

 

Ami engem érdekelt telepítés után, az az OP rendszer és az SQL Server kapcsolata. Itt olyan jellegű SQL utasításokra gondolok, amik Windows-on pl.: a registryben matatnak vagy a fájlokhoz köthetőek valahogy. Voltak, amik nem ment ment, szóval majd doksikat kell néznem 🙂 De ezt leszámítva eddig minden más rendben volt.

 

 

LIKE és az ESCAPE

A LIKE-ot szerintem mindenki ismeri, de az ESCAPE záradékát már kevesebben, pedig nagyon hasznos tud lenni. Erről írok most egy rövid postot.

Az ESCAPE kiegészítés akkor hasznos, amikor egy foglalt karakter is szerepelne a keresésben. Ilyen karakterek jelenleg: [,],%,_,^

Tehát, ha van egy ilyen változónk: @a = ‘ertek%ertek’ és azt akarjuk tudni, hogy @a változóban található e % jel, akkor escape-elni kell. Az escape karakter bármi lehet, a lényeg, hogy az escape záradékban adjuk meg, hogy mi volt az. A továbbiakban minden szónál többet fognak érni a példák, úgyhogy jöjjön a demó.

Készítünk egy táblát, teszünk bele % jeles értékeket és szűrünk többféle variációban (Százalékjel helyett lehetne más foglalt karakter is, én most ezzel demózok).

IF OBJECT_ID('tempdb..#tmp') IS NOT NULL
DROP TABLE #tmp
GO

CREATE TABLE #tmp (name VARCHAR(16) NULL)

INSERT INTO #tmp (name)
VALUES
(NULL),
('ertek%ertek'),
('ertekertek'),
('%'),
('%ertek'),
('ertek%'),
('e%rtek'),
('erte%k')

 

Próbáljuk keresni a hagyományos módszerrel a % jelet:

-- 1.) Elso teszt
SELECT [name]
FROM #tmp
WHERE name LIKE '%%%'

01_elso_teszt

Azt látjuk, hogy visszakaptuk a teljes tábla tartalmát a NULL kivételével. De nem ezt akartuk.

Használjuk ez escape-elést.

-- 3.) Szazalekjel van valahol az ertekben
SELECT [name]
FROM #tmp
WHERE name LIKE '%!%%' ESCAPE '!'

03_szalaekjel_valahol
Egész jó, itt már azt kaptuk, amit akartunk. Bonyolítsuk néhány dologgal, a további példák már csak ráadások.

-- 4.) Szazalekjel van valahol az ertekben, de a szazalekjel elott van legalabb egy karakter
SELECT [name]
FROM #tmp
WHERE name LIKE '%_!%%' ESCAPE '!'

04_szazalekjel_valahol_plusz_elotte_1_karakter

 

-- 5.) Szazalekjel van valahol az ertekben, de a szazalekjel utan van legalabb egy karakter
SELECT [name]
FROM #tmp
WHERE name LIKE '%!%_%' ESCAPE '!'

05_szazalekjel_valahol_plusz_utana_1_karakter

 

-- 6.) Szazalekjellel kezdodik az ertek
SELECT [name]
FROM #tmp
WHERE name LIKE '!%%' ESCAPE '!'

06_szazalekjellel_kezdodik

 

-- 7.) Szazalekjelre vegzodik az ertek
SELECT [name]
FROM #tmp
WHERE name LIKE '%!%' ESCAPE '!'

07_szazalekjelre_vegzodik

 

-- 8.) Szazalekjel elott csak 1 db karakter all
SELECT [name]
FROM #tmp
WHERE name LIKE '_!%%' ESCAPE '!'

08_szazalekjel_elott_1_karakter_utana_barmennyi

 

-- 9.) Szazalekjel utan csak 1 db karakter all
SELECT [name]
FROM #tmp
WHERE name LIKE '%!%_' ESCAPE '!'

09_szazalekjel_utan_1_karakter_elotte_barmennyi

 

-- 10.) Szazalekjel utan 'e' vagy 'r' vagy 'k' aztan barmi
SELECT [name]
FROM #tmp
WHERE name LIKE '%!%[erk]%' ESCAPE '!'

10_szazalekjel_utan_erk_aztan_barmi

-- 11.) Szazalekjel utan 'e' vagy 'r' vagy 'k' aztan vege
SELECT [name]
FROM #tmp
WHERE name LIKE '%!%[erk]' ESCAPE '!'

11_szazalekjel_utan_erk_aztan_vege

 

Van még a LIKE-nak jó tulajdonsága, bővebben BOL-ban lehet utána olvasni.

Ha valakinek van kedve még ezzel játszani, akkor itt egy feladat: A meglévő táblába szúrjunk be további 2 értéket:

INSERT INTO [#tmp] ( [name] ) VALUES  ( 'ertek%[[ertek]]')
INSERT INTO [#tmp] ( [name] ) VALUES  ( 'ertek%[ertek]')

És most keressük ki azokat az értékeket, ahol:

  1. A ‘%’ jel után ‘[‘ jel áll. (Tehát ‘%[‘)
  2. A ‘%’ jel után ‘[‘ jel áll, utána pedig NEM ‘[‘ jel. (Tehát ‘%[‘ majd nem ‘[‘). Ez utóbbit a cikk alapján nem tudod megoldani, el kell olvasni a BOL-t, ha nem tudod a megoldást.

Végezetül pedig, ha nagyon bonyolult regex-es kifejezésekre van szükségünk, akkor használjunk hozzá CLR-t.