Tímto příkazem lze vkládat části řetězce do jiného, popř. při tom smazat určitý počet znaků

1
SELECT STUFF (PuvodniText, PoziceVlozeni, KolikZnakuSmazat, CoVlozit)

Příklad: Text 'Tonda není žádný blbec' potřebujeme změnit

1
SELECT STUFF ('Tonda není žádný blbec',7,10,'je')

Výsledek: Tonda je blbec

Někdy nastane situace, kdy je třeba zpracovat sadu příkazů opakovaně. K tomu lze použít příkaz WHILE.
Pokud je splněna podmínka definovaná za WHILE je zpracován blok příkazů mezi BEGIN a END. Na konci bloku je opět testovaná podmínka a pokud je splněna cyklus probíhá opakovaně. Pokud v průběhu cyklu potřebujeme zpracování ukončit a pokračovat ve zpracování příkazů za cyklem použijeme příkaz BREAK. Naopak, pokud chceme pokračovat dále, použijeme CONTINUE (vzhledem k tomu, že smyčka by beztak pokračovala dále, tak se CONTINUE prakticky nepoužívá)

1
2
3
4
5
6
7
WHILE Podmínka
 
BEGIN
  Příkaz 1
Příkaz 2   ..... END

 

Praktická ukázka i s použitím BREAK

1
2
3
4
5
6
7
8
9
10
11
12
13
14
DECLARE @PocitadloCyklu INT
SET @PocitadloCyklu = 0
 
WHILE @PocitadloCyklu < 10
BEGIN
  PRINT 'Cyklus: ' + CAST(@PocitadloCyklu AS nvarchar)
  SET @PocitadloCyklu = @PocitadloCyklu + 1
  IF @PocitadloCyklu = 8 
    BEGIN
      PRINT 'Přerušení smyčky'
      BREAK
    END	
  ELSE CONTINUE
END

Pozn. Cyklus by měl proběhnout 10x, ale vzhledem k podmínce uvnitř cyklu skončí při 7-mém průběhu

Výsledek:

Sloučit více textových řetězců do jednoho můžeme dvěma způsoby.

1) Součet textových řetězců

Toto řešení vypadá jednoduše, ale musíme dát pozor na dvě věci. 
A) sčítaná proměnná nesmí mít hodnotu NULL protože výsledek by byl také null
B) číslo je třeba přetypovat na text 

1
2
3
4
SELECT Text1 + Text2 + Text3
 
--příklad
SELECT 'Text1' + ' ' + 'Text2'

2) Použití CONCAT

Toto řešení má výhodu, že mu nevadí hodnota NULL a k číslům se chová jako k textu (což ovšem někdy může být nežádoucí)

1
2
3
4
SELECT CONCAT (Text1,Text2,Text3,....)
 
--příklad
SELECT CONCAT ('Text1',' ','Text2')

 

Příklad sloučení textových a číselných hodnot.

1
2
3
4
5
6
7
8
DECLARE @Text nvarchar(20) = 'Výsledek je '
DECLARE @Cislo numeric(19,2) = 123.4
DECLARE @Mena nvarchar(3) = ' Kč'
 
--metoda 1
SELECT @Text + CAST(@Cislo AS nvarchar) + @Mena +' !!!'
--metoda 2
SELECT CONCAT (@Text, @Cislo, @Mena,' !!!')

Obě metody vrátí stejnou hodnotu: Výsledek je 123.40 Kč !!!

 

 

Jsou občas situace, kdy si zaťukáte na čelo "Jak tohle mohl někdo vymyslet". Třeba dnes jsem řešil v podnikovém IS přepočet jednotek na kartách zboží. Nějaký můj předchůdce vyrobil na kartách zboží "okýnko" do kterého se zapisuje přepočítací koeficient. A to tak že včetně měrných jednotek takže např: "18,33 kg/m" No a teď po mě chtějí naprogramovat počítatelný sloupec, kde se bude automaticky počítat hmotnost skladové položky. A jak mám asi násobit textovým řetězcem? :-)
Takže řešením bylo naprogramovat dva nové sloupce - číselný pro koeficient a textový pro měrné jednotky. No a aby obchoďáci nemuseli přepisovat hodnoty asi u 13 tisíc karet, vyrobil jsem si script na nakrmení nových polí z původních hodnot.

Zde je skript a lze použít i na jakékoliv vyseparování textových nebo číselných hodnot ze smíšeného řetězce.

Nutno dodat, že k výsledku jsem došel ještě i jinou cestou, ale nakonec jsem si pro univerzálnost zvolil toto řešení.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
DECLARE @Vstup nvarchar(30)          
DECLARE @Znak nvarchar(1)
DECLARE @CisloText nvarchar(100)
DECLARE @Cislo numeric(19,2)
DECLARE @Text nvarchar(100)
DECLARE @DelkaRetezce int
 
SELECT @Vstup = REPLACE (@Vstup,',','.')	-- nahrazení čárky za tečku u deset.č
SELECT @Vstup = LTRIM(RTRIM (@Vstup))		-- odstraneni mezer na zacatku a konci
 
SELECT @DelkaRetezce = LEN(@Vstup)		-- délka řetězce (počet cyklů smyčky)
 
-- začátek smyčky
WHILE @DelkaRetezce > 0   
BEGIN
 
SELECT @Znak =  RIGHT (@Vstup,1)		-- poslední znak řetězce
 
IF @Znak NOT LIKE '[0-9.]'			   -- posouzení, zda se jedná o číslo
SELECT @Text = CONCAT (@Znak, @Text)	           -- sloučení znaků v případě textu 
ELSE
SELECT @CisloText = CONCAT (@Znak, @CisloText)	-- sloučení znaků v případě čísla
 
SELECT @Vstup = STUFF (@Vstup,@DelkaRetezce,1,'') -- odmazání posledního znaku
SET @DelkaRetezce = @DelkaRetezce -1		  -- snizeni poctu cyklu o jeden
 
END
-- konec smyčky 
  
SELECT @Text = LTRIM(RTRIM (@Text))		-- odstraneni mezer na zacatku a konci
SELECT @Cislo = (CAST(@CisloText AS Numeric(19,2))) -- přetypování textu na číslo

 

 

Vstup: @Vstup= '18,3 Kg/m'
Výsledek: @Text='Kg/m' , @Cislo = 18.30

Vstup: @Vstup= '   1  8,3   Kg/m  '
Výsledek: @Text='Kg/m' , @Cislo = 18.30

Vstup: @Vstup= 'Ton12da55Kouta44'
Výsledek: @Text='TondaKouta' , @Cislo = 125544.00

Pozn: vstupní proměnná je @Vstup, výstupní jsou @Text a @Cislo

 

Jak skript funguje? Triviálně. Posuzuje vždy poslední znak v řetězci, pokud znak není číslo, přidá ho do proměnné @Text, jinak ho přidá do proměnné @CisloText. Pak poslední znak odmaže a pokračuje opět v porovnávání posledního znaku. Nakonec odstraní mezery na začátku a konce textu a číslo přetypuje z textového řetězce na desetinné číslo.

Jak říkám, k výsledku lze dojít i jinou cestou, ale mě se tato líbí pro možnou modifikaci a užití i na jiné případy.

 

 

 

Tímto způsobem můžeme v řetězci zaměnit část textu. 

1
SELECT REPLACE (Vstup, PuvodniZnak, NovyZnak)

 

Příklady

1
SELECT REPLACE ('10/10/2017, '/', '.')

Výsledek: 10.10.2017

1
SELECT REPLACE ('Tonda je borec','borec','blbec')

Výsledek: Tonda je blbec

 

 

Původně to měla být kategorie o cestách, které podniknu na svém starém kole-dědkovi. Pak se mě název zalíbil a říkám si, že jednou budu taky dědek, vlastně syna už na to mám dost velkýho, a tak nadčasově tuto kategorii nechám pojmenovanou takto. Takže zde nalezneš zápisky z cest. 

Zde je můj blog o SQL. Je to takový můj tahák.

Moje poznámky z instalací