Category Archives: Development

Uložení výsledku stored procedury pomocí SELECT INTO

Když neznáme přesnou strukturu výsledku stored procedury, nemůžeme použít CREATE TABLE a INSERT … EXEC. Dá se to obejít pomocí OPENQUERY:

exec sp_serveroption [SERVER_NAME] , 'data access', 'true'

SELECT * INTO #W FROM OPENQUERY([SERVER_NAME], 'exec sp_who')
SELECT * FROM #W

SQL: Doplňování (padding) čísel nulami zleva na pevný počet míst (15 -> 00015)

Možná to jde lépe, ale co třeba takto:

= REPLACE(STR(15, 5, 0), ' ', '0')

Funkce STR(num, length, decimals) převede číslo na řetězec určené délky (doplněný zleva mezerami) a s daným počtem desetinných míst.

Nebo takto?

= RIGHT('00000' + cislo, 5)

Většinou si formátování řešíme až v prezentační vrstvě, ale někdy se to může hodit…

SQL: Určení věku osoby z data narození

Vypadá to jako triviální problém, nicméně triviální řešení zde nejsou správná.

Nejprve tedy správné řešení:

/*
   Vrátí věk ke vztažnému datu určený dle data narození.
*/
ALTER FUNCTION dbo.Age 
(
   @DatumNarozeni smalldatetime,
   @VztazneDatum smalldatetime
)
RETURNS tinyint
AS
BEGIN
   RETURN DATEDIFF(year, @DatumNarozeni, @VztazneDatum)
      - (CASE WHEN (100 * MONTH(@VztazneDatum) + DAY(@VztazneDatum)) < (100 * MONTH(@DatumNarozeni) + DAY(@DatumNarozeni))
              THEN 1 ELSE 0 END)
END

A pár ukázek špatných řešení:

DATEDIFF(year, @birthdate, @enddate)

SELECT DATEDIFF (year, @birthdate, @endDate)
  - CASE WHEN DATEPART(dy, @birthdate) <= DATEPART(dy, @endDate) THEN 1 ELSE 0 END

První pokus od sebe jen odečte letošní letopočet od letopočtu narození.
Druhý pokus zase nefunguje korektně s přestupnými roky, protože pak není počet dnů od 1.1. stejný.

Cannot resolve collation conflict for UNION operation.

Zajímavá hříčka, která může klidně skončit chybou „Cannot resolve collation conflict for UNION operation.“

SELECT * FROM RealTable INTO #temp WHERE ...

SELECT * FROM #temp
UNION
SELECT * FROM RealTable 

Dejme tomu, že RealTable používá default database collation.
Přestože výše uvedené vypadá, že přeci nemůže být s COLLATION problém, může být.
#temptable se totiž vytváří v databázi tempdb, která může mít jiné collation, než naše user-databáze!!! …a problém je na světě.

DirectoryNotFoundException: Could not find a part of the path „C:\“.

Takovoudle prima výjimku dostaneme, pokud voláme System.IO.Directory.CreateDirectory(String path) a nemáme přístupová práva alespoň na prohlížení všech nadřazených složek, typicky třeba chceme-li vytvořit novou složku z webové aplikace.

Directory.CreateDirectory() totiž neslouží jen pro založení jedné složky, ale pokud je potřeba, vytvoří celou požadovanou cestu, založí všechny potřebné složky. Základní potíž je v tom, že si nekontroluje existenci složek zdola, ale shora. Takže požadavek na založení složky C:\Inetpub\wwwroot\WebApplication\slozka\ kontroluje nejprve existenci C:\, pak C:\Inetpub\, pak C:\Inetpub\wwwroot\. No a pokud nemáme práva alespoň LIST na celou trasu, tak jsme v loji…

HttpContext.Current.Cache vs. HttpRuntime.Cache

Jaký je rozdíl mezi HttpContext.Current.Cache oproti HttpRuntime.Cache?

Zdá se to být jednoduché, HttpContext.Cache dělá

public Cache get_Cache()
{
      return HttpRuntime.Cache;
}

Proč tedy používat HttpContext.Current.Cache?
Není důvod!!! Správné použití je HttpRuntime.Cache !!!
Když pomineme režii na vyhodnocení HttpContext.Current, tak je tu ještě jeden zcela zásadní důvod, proč používat HttpRuntime.Cache. Ten totiž funguje i v nových threadech, kde je HttpContext.Current null. A nejenom to, funguje dokonce i mimo webové aplikace, třeba v konzolovce.

Viz též