Přejít k navigační liště

Zdroják » PHP » GIS, PHP a SQL Server 2008

GIS, PHP a SQL Server 2008

Články PHP, Různé

Geografické informační systémy (GIS) nabývají na stále větší důležitosti. Základem jsou, kromě dat, specializované databáze, které si poradí s úlohami typu „Najdi obce, které jsou do vzdálenosti 1 km od dálnice D1“. S tím pak samozřejmě souvisí vizualizace dat na mapách. Ukážeme si, jak vytvořit jednoduchou GIS aplikaci.

Nálepky:

Výsledkem našeho snažení bude webová aplikace, která dokáže zobrazit obrysy krajů v ČR a najít obce, které leží ve vybraném kraji. U obcí máme k dispozici jen název a jejich geografické souřadnice, u krajů opět název a souřadnice popisující hranici kraje. Vzorová data pro kraje jsem použil z webu gc.fa-fa.org a souřadnice obcí, které jsou hodně přibližné, jsem našel kdysi na internetu, ale zdroj si již nepamatuji.

Cílem není vytvořit aplikaci připravenou k ostrému provozu, ale ukázat koncept. K zobrazení informací použijeme Virtual Earth Map Control, o zpracování dat na serveru se bude starat PHP a na klientovi jQuery. GIS funkce bude zajišťovat SQL Server 2008.

SQL Server 2008

Jednou z mnoha novinek v SQL Serveru 2008 je podpora geografických dat, která je postavena na doporučeních Open Geospatial Consortium. Podpora práce s geografickými informacemi je dostupná i v edici SQL Server 2008 Express, která je zdarma i ke komerčním účelům. Doporučuji stáhnout edici SQL Server 2008 Express with Advanced Services, která kromě databázového jádra obsahuje podporu pro fulltext a Reporting Services pro vytváření „tiskových“ sestav. SQL Server 2008 Express má oproti „dospělému“ SQL Serveru některá omezení:

  • Maximální velikost databáze je 4 GB
  • Nevyužije víc než 1 GB RAM
  • Nevyužije víc než 1 procesor, resp. jádro

Všechny edice SQL Server 2008 mají identické jádro, takže není problém mezi edicemi databázi přenášet. Edice se liší v podporovaných službách a v limitech využití HW.

Instalace

Součástí instalace je nástroj System Configuration Checker, který ověří, zda počítač splňuje systémové požadavky pro SQL Server 2008.

SQL Server Installation Center

Úvodní okno instalace

SQL Server 2008 Setup

Kontrola systémových požadavků

Pravděpodobně nebudete mít nainstalovaný Powershell, který SQL Server 2008 využívá pro konfiguraci z příkazové řádky. Dále budete potřebovat .NET Framework 3.5, ten si ale umí instalátor SQL Serveru 2008 nainstalovat sám. Další, na co je třeba myslet, jsou účty pro běh jednotlivých služeb SQL Serveru. SQL Server 2008 se skládá z několika služeb (databázové jádro, fulltext, Reporting Services, Integration Services…) a v produkčním prostředí se pro běh každé služby doporučuje použít samostatný uživatelský účet se základními právy (skupina Users), který se k ničemu jinému nepoužívá. Na testovacím stroji můžete nechat vše běžet pod jedním účtem. Celý postup instalace si můžete prohlédnout v screencastu.

Připojení se k SQL Serveru 2008

Pro správu SQL Serveru 2008 se používá nástroj SQL Server Management Studio, který je součástí instalace. Slouží jak ke správě serveru, tak jednotlivých databází a k ladění dotazů a procedur. Při spuštění nastavíte umístění serveru a typ autentizace. Pokud se připojujete k lokálnímu počítači, můžete místo názvu počítače použít (local). Za zpětným lomítkem je uveden název instance SQL Serveru, který jste vytvořili při instalaci.

Connect to Server

Vytvoření databáze

  1. Pravým tlačítkem myši klikněte na větev Database v Object Explorer
    New Database
  2. Vyberte New Database…
    New Database
  3. V podstatě stačí jen vyplnit jméno databáze. V produkčním prostředí se doporučuje mít databázové soubory na jiném pevném disku než soubor pro transakční log. Stejně tak by datové soubory měly být jinde, než je disk s operačním systémem a aplikacemi. Pro vývoj můžeme klidně vše nechat na jednom disku.
  4. Kliknutím na OK se databáze vytvoří ve vybraném umístění.

Alternativa

Veškerou správu SQL Serveru 2008 můžete dělat pomocí SQL příkazů z příkazové řádky nástrojem sqlps (klasický Powershell obsahující nástroje pro SQL Server 2008). Následující ukázka je vytvoření nové databáze. Stejně tak můžete vytvářet tabulky, uživatele, indexy,…

  1. Spusťte sqlps
  2. Spusťe příkaz: Invoke-Sqlcmd -Query "CREATE DATABASE CR;" -ServerInstance "(local)SQLEXPRESS"

Vytvoření tabulek

  1. Rozbalte strom nově vytvořené databáze
    New Table
  2. Vyberte New Table…
    New Table
  3. Po vytvoření struktury tabulky stačí kliknout na tlačítko Save nebo Ctrl+S a tabulku pojmenovat.

Indexy

Indexy výrazně urychlují zpracování dotazů. Bez dobře navržených indexů jsou objemné databáze a databáze pro GIS naprosto nepoužitelné z hlediska výkonu. I v našem jednoduchém příkladu na použití GIS funkcí se budou dotazy vykonávat v desítkách sekund, pokud nebudeme mít vytvořené indexy pro geografická data. Pro ladění indexů se používá okno Execution plan, které zobrazíte z nabídky Query. V tomto okně vidíte, zda se používají indexy. Následující screenshot ukazuje dotaz bez použití indexů. Vidíte, že se to „zaseklo“ na filtrování dat z tabulky Obce. Doba trvání dotazu byla cca 35 sekund:

Doba trvání dotazu

Tady jsem přidal index na sloupec Obce.Souradnice, který obsahuje geografické informace. Doba trvání dotazu byla těsně pod 2 sekundy:

Doba trvání dotazu

Z ukázek je jasně vidět, že stačilo přidat pouze jeden jediný index a odpověď z databáze je výrazně rychlejší. A výsledek by šel dál zlepšit.

Vytvoření indexu

  1. Rozbalte větev tabulky v Object Explorer
  2. Pravým tlačítkem myši klikněte na Indexes
    New Index
  3. Dále je třeba index pojmenovat a přidat sloupce, nad kterými chcete index vytvořit. Pokud chcete vytvořit index pro datový typ geography, geometry nebo xml, je třeba také změnit vlastnost Index type.
    New Index

Relace

U vytvoření relace mezi dvěma tabulkami je třeba začít otevřením stromu objektů tabulky, která bude obsahovat cizí klíč (Foreign Key).

  1. Klikněte pravým tlačítkem myši na seznam klíčů (Keys) a vyberte New Foreign Key…
    New Foreign Key
  2. Vyplňte jméno klíče (Name)
    Foreign Key Relationships
  3. V řádku Table and Columns Specification klikněte na tlačítko v pravé části řádku
    Tables and Columns
  4. Vlevo nastavte tabulku s primárním klíčem a pole, které ho obsahuje, vpravo pak nastavte provázané pole

Několik dobře míněných rad pro vytváření databází

Na co se často zapomíná u popisu jak vytvořit databázi, je, jak ji navrhnout. Nečiním si nárok zde popsat teorii relačních databází, ale spíše se jedná o dobře míněné rady, které jsou často ignorovány:

  • Každá tabulka by měla obsahovat jen informace jednoho typu. Viděl jsem, jak se někteří snažili celou databázi nacpat do jedné tabulky. Bohužel jde o zlozvyk z tabulkových kalkulátorů.
  • Pole tabulky by mělo být dále nedělitelné. Klasickou ukázkou je ukládání celého jména osoby do jednoho pole. Jeden můj kamarád se jmenuje Petr Štěpán. Co je jeho křestní jméno?
  • Pokud mám jednu informaci, na kterou se váže více informací jiných (osoba – poštovní adresa, fakturační adresa, doručovací adresa), tak je třeba informace rozdělit do více tabulek a nastavit mezi nimi relaci. Už jsem viděl tabulku, kde bylo pole Ulice1 až Ulice 7, PSC1 až PSC7, atd. V příkladu adres, který jsem uvedl, bych vytvořil tři tabulky a ty provázal přes klíče:
    • Osoba
    • Adresa
    • Typ adresy
  • Chybějící indexy a špatně sestavené dotazy nedoženete sebelepším HW. Jeden můj kolega, po kterém jsem v předchozím zaměstnání přebíral projekt, vytvořil report, který se generoval 5 hodin. Po přidání indexů se generoval 30 minut a po dalším odladění 4 minuty…
  • Pokud neděláte relace mezi souvisejícími tabulkami, tak je pro vás relační databáze zbytečná a dřív nebo později si porušíte referenční integritu dat. V kódu to neuhlídáte.
  • Soubory, které mají vztah k informacím v databázi, ukládejte do databáze, zjednodušíte si zálohování a konzistenci dat se zbytkem databáze. Pomocí atributu FILESTREAM u pole typu varbinary(MAX) můžete ukládat soubory do velikosti, kterou podporuje souborový systém na serveru.

Zabezpečení

Abyste databázi mohli používat pro webovou aplikaci, musí do ní mít přístup uživatel, pod kterým běží některý Application Pool na IIS.

Aplication Pools

Webová aplikace pak musí být přiřazena do příslušného Application Pool:

Advanced Settings

A uživatel ApplicationPoolu musí mít vytvořen Login na databázovém serveru, případně musí být ve skupině, která na databázovém serveru Login už má:

Login Properties

Jak je vidět, pro testovací účely jsem si vytvořil Application Pool, který běží pod mým doménovým účtem, který má nastavenu roli sysadmin databázového serveru. Pro produkční nasazení je třeba vytvořit účet, který bude mít ta nejnižší nutná práva jak k systému, tak databázi (role db_datareader), aby se snížilo riziko zneužití účtu.

Podpora GIS

Jedna z novinek SQL Serveru 2008 je nový typ geography určený pro uchovávání geografických informací a práci s nimi. Typ geography je .NET CLR objekt, který zároveň umí s geografickou informací i manipulovat (hledat průniky, převádět na text, z textu na geografický objekt, počítat rozměry atd.). Pro vkládání dat do sloupce s typem geography se používá Open Geospatial Consortium (OGC) Well-Known Text (WKT). Ukázka:

INSERT INTO Obce
           (Nazev
           ,Souradnice)
     VALUES
           ('Praha',
            geography::STGeomFromText('POINT(50.0668 14.4662)', 4326)) 

Druhý parametr metody STGeomFromText určuje použitý souřadnicový systém, zde konkrétně WGS 84. Pro zpětné získání geografických dat se požívají metody pro naformátování výstupu buď do WKT, nebo GML:

select Souradnice from Obce where ObecId = 1 

vrátí

0xE6100000010C58CA32C4B1EE2C40B8AF03E78C084940 
select Souradnice.ToString() from Obce where ObecId = 1 

vrátí

POINT (50.0668 14.4662) 
select Souradnice.AsGml() from Obce where ObecId = 1 

vrátí

<Point xmlns="http://www.opengis.net/gml"><pos>14.4662 50.0668</pos></Point> 

Seznam podporovaných metod pro práci s geografickou informací (průnik, plocha, vzdálenost …) najdete na MSDN.

Pár ukázek (pro přehlednost jsou některé rozepsané do více kroků, vše lze samozřejmě udělat i jedním SELECTem):

Plocha Karlovarského kraje:

select Nazev, Oblast.STArea() as Plocha from Kraje where KrajId = 5 

Vzdálenost Praha – Liberec:

DECLARE @Praha geography;
DECLARE @Liberec geography;
select @Praha = Souradnice from Obce where Nazev = 'Praha'
select @Liberec = Souradnice from Obce where Nazev = 'Liberec'
SELECT @Praha.STDistance(@Liberec); 

Obce v okruhu 10 km od Vlašimi:

DECLARE @Vlasim geography;
SELECT @Vlasim = Souradnice From Obce Where Nazev = 'Vlašim'
SELECT Nazev From Obce Where @Vlasim.STBuffer(10000).STIntersects(Souradnice) = 1; 

Další informace o SQL Serveru 2008 najdete v elektronické knize Introducing Microsoft SQL Server 2008, která je zdarma ke stažení.

SQL Server 2005 Driver for PHP

Abychom mohli využívat SQL Server 2008, je třeba si stáhnout SQL Server 2005 Driver for PHP. I když je v názvu uveden SQL Server 2005, tak ovladač funguje i s SQL Server 2008. K připojení využívá SQL Native Client. Instalace obsahuje dvě knihovy ovladače php_sqlsrv.dll (non-thread safe), php_sqlsrv_ts.dll (tread safe) a dokumentaci. Instalace je velmi jednoduchá. Ovladač nakopírujete k ostatním knihovnám PHP, typicky adresář ext v instalačním adresáři PHP a knihovnu přidáte do php.ini. Ve výstupu funkce phpinfo() byste měli pak najít sekci sqlsrv.

Výpis funkce phpinfo

Pomocí funkce sqlsrv_connect získáte kontext připojení k databázi. Funkce má dva parametry – adresu serveru a pole parametrů, ve kterém můžete specifikovat vlastnosti připojení – jméno databáze, přihlašovací údaje, využití connection pool atd. Pokud neuvedete přihlašovací údaje, použije se Windows authentication.

$serverName = '(local)SQLEXPRESS'; // adresa serveru
$connectionInfo = array( 'Database'=>'CR'); // parametry pripojeni
$conn = sqlsrv_connect( $serverName, $connectionInfo); 

SQL dotaz se provádí funkcí sqlsrv_query, která má jako jeden z parametrů vlastní dotaz, dále pak kontext připojení. Pokud používáte parametrizované dotazy, což je z hlediska bezpečnosti před útokem typu SQL Injection naprosto nezbytné, budete jako další parametr funkce předávat pole hodnot, které nahradí parametry v dotazu. Nahrazení parametrů v dotazu za konkrétní hodnoty se provádí až na SQL Serveru, v době, kdy je hotový Execution Plan. Tím pádem není už možné vykonat podstrčené dotazy v parametrech.

$sql = 'SELECT o.Nazev, o.Souradnice.ToString()
                FROM Obce o, Kraje k
                WHERE k.Oblast.STIntersects(o.Souradnice) = 1
                    AND k.KrajId = ?
                ORDER BY o.Nazev';
 
 $stmt = sqlsrv_query($conn, $sql, array($_GET['id'])); 

Pro čtení výsledku dotazu se používá smyčka while a funkce sqlsrv_fetch, které jako parametr předáte dotaz.

while(sqlsrv_fetch( $stmt))
{
...
} 

Pro získání konkrétní hodnoty použijete funkci sqlsrv_get_field, kde první parametr určuje sloupec (indexováno od nuly), druhý sloupec je dotaz, který zpracováváte, a třetí parametr je datový typ navrácené hodnoty. To potřebujete ve chvíli, kdy máte textová data v databázi uložena v Unicode (datová pole nvarchar, nchar, ntext). Zpracování textu uloženého v Unicode:

$name = iconv("utf-16le"
                    "utf-8",
                    sqlsrv_get_field($stmt,
                        0,
                        SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY))); 

Další funkce pro načítání dat jsou sqlsrv_fetch_array a sqlsrv_fetch_ob­ject. Práce s úložnými procedurami (Stored Procedures) je v podstatě identická s prací s klasickým SQL:

CREATE PROCEDURE [dbo].[GetPolygon]
@id int
AS
BEGIN
SELECT Nazev, Oblast.ToString() as polygon FROM Kraje WHERE KrajId = @id
END
 
$sql = 'execute GetPolygon ?';
$stmt = sqlsrv_query($conn, $sql, array($_GET['id'])); 

Vizualizace dat

Pro vizualizaci geografických dat je asi nejdostupnější použít některou z veřejných mapových služeb. Pro toto demo jsem zvolil Virtual Earth Map Control. Vložení mapy do stránky a její ovládní pomocí JavaScriptu vyžaduje v podstatě dvě věci.

  • Přidat odkaz na javascriptovou knihovnu Virtual Earth Map Control
  • Vytvořit element <div>, kde se bude mapa zobrazovat

Základní zobrazení mapy ve stránce:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>Virtual Earth Example</title>
 
    <script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2" type="text/javascript"></script>
    <script type="text/javascript">
    var map = null;
 
    function OnPageLoad()
    {
        map = new VEMap('map');                 
        map.LoadMap(new VELatLong(50.0, 14.5));                                
    }
    </script>
 
</head>
<body onload="OnPageLoad()">
    <div id="map" style="width: 800px; height: 600px; overflow: hidden;">
    </div>
</body>
</html> 

Ve chvíli, kdy máme mapu zobrazenou, můžeme na ni přidávat další vrstvy s vlastní grafikou. Následující ukázka přidá bod na mapu ve vlastní vrstvě:

var layer = new VEShapeLayer();
var shape = new VEShape(VEShapeType.Pushpin, new VELatLong(50, 14.5));
shape.SetTitle('Praha');
layer.AddShape(shape);                                         
map.AddShapeLayer(layer); 

Co může zobrazení dat usnadnit, je podpora formátů GeoRSS a KML.

var layer = new VEShapeLayer();
var veLayerSpec = new VEShapeSourceSpecification(VEDataType.GeoRSS, 'rss.xml', layer);
map.ImportShapeLayerData(veLayerSpec); 

Závěr

Ukázkovou aplikaci si můžete stáhnout, popřípadě vyzkoušet online.


Autorem článku je Štěpán Bechynský, specialista pro vývojové nástroje ve společnosti Microsoft v České republice. Informace pro vývojáře také najdete na blogu odborníků z českého Microsoftu.

Komentáře

Subscribe
Upozornit na
guest
10 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
Jáchym Čepický

Ve světě GIS je „de-facto“ standardem PostGIS. Je to OpenSource nadstavba databáze PostgreSQL. Tu si může každý stáhnout a nainstalovat zadarmo a bez omezení, stejně jako PostGIS. Není snad ve světe FOSS4G (Free and Open Source Software for Geoinformatics) produkt, který neuměl s PostGISem pracovat. Existují převodní filtry (součástí distribuce) mezi PostGIS a ESRI Shapefile a OpenStreetMap. Pro vyhledávání nejvýhodnější cesty se doporučuje PgRouting a další a další nadstavby. PostGIS je certifikován na podporu OGC Simple Features Specification for SQL. Tolik velmi z rychlíku.

4326 je kód souřadného systému WGS84, jak jej definuje EPSG. Není to proto jen tak ledasjaký kód, ale EPSG:4326. (Pokud si myslíte, že je to nepodstatný detail, nepište články o GIS).

Otázka za 100 bodů: Jaký EPSG (nebo jiný) kód byste použil ve funkci STGeomFromText pro v ČR používaný souř. systém S-JTSK? A podporuje ho MS SQL 2008? Protože když chcete psát aplikace, mající co do činění např. s katastrem nemovitostí, je převod WGS84<->S-JTSK dosti zásadní.

Komu PostgreSQL nestačí (do PostGIS se ale toho vejde opravdu hodně), tak používá Oracle Spatial

Jinak si myslím, že článek patří spíš do kategorie PR.

Jáchym Čepický

Nic, protože jste neuhád'. Kód 4156 má projekci Lat/Long a Besselův elipsoid. Takže výsledek jsou stupně/minuty/vteřiny, ale S-JTSK je metrický systém, používající tzv. Křovákovo zobrazení. Data v KN (a vůbec všechno, co měří, a není to v „souřadnicích GPS“ – příšerný 'termín') používají přece metry (stopy, atd. podle místních zvyklostí), ale ne stupně. Ostatně, co vrátí funkce ST_Length(geometry), kde geometry je nějaká linie v EPSG:4156? Metry?

-- vybere nejdelsi dalnici v CR z aktualni OSM. 
-- Geometrie je ulozena ve sloupecku way v EPSG:4326, musi byt pred tim pretranformovana do 4156
-- PostGIS
select sum(length(ST_Transform(way,4156))) as len,name,ref  FROM cr_osm_line WHERE highway is not NULL and ref is not null group by name,ref order by len desc limit 1;
       len        | name | ref 
------------------+------+-----
 6.09415397247231 |      | D1

je ve stupnich

-- prevod do epsg:102067
select sum(length(ST_Transform(way,102067))) as len,name,ref  FROM cr_osm_line WHERE highway is not NULL and ref is not null group by name,ref order by len desc limit 1; 
       len       | name | ref 
-----------------+------+-----
 488855.79704467 |      | D1

Je v metrech – tam i zpatky.

Cimz si odpovidam na puvodni otakzu: To byl chytak, S-JTSK nema EPSG kód (resp. žádný použitelný) a obecně se používá ESRI:102067 (v praxi častěji EPSG:102067).

No, ale aby nic nebylo tak jednoduché – definice pro 102067 se musí do všech databází/GISů a pod. doplnit ručně, protože takový kód vlastně neexistuje. Ale ukazovat příklad nad WSG84 mi opravdu nepřijde jako vhodné. GIS nejsou jenom GPSky.

Štěpán

Křovákovo zobrazení má již dávno svůj oficiální EPSG kód: 2065. Problém je v tom, že svislá osa je X a je orientována shora dolů (je tedy levotočivá). Protože větišna GIS software s takouvouto soustavou neumí pracovat (kdysi kromě sw TopoL, dnes nevím, jaký je aktuální stav), používají se souřadnice prohozené a záporně označené (tzv. ve 3. kvadrantu). Protože je to berlička a ne oficiální projekce, není ani v oficiální databázi EPSG. Třeba v budoucnu…?

Použití zeměpisných souřadnic WGS84 pro tento typ aplikací mi připadá naprosto adekvátní, protože různé mapové API umějí právě s těmito souřadnicemi pracovat, jednak použití Křovákova zobrazení končí za hranicemi naší vlasti…

xurpha

Zase ty Micro$osfti nesmysly? Podporu GIS má už i mysql, tak nechápu, co tady prudíte, jdete si na nejaky server pro klikajici blbecky! (navíc je to samý nesmyslný obrázky…)

Jáchym Čepický
tomas

Jediný, kdo je tady blbeček, jste vy. Když se vám nelíbí články týkající se technologií jistých firem, tak je prostě nečtěte a nemusíte svůj názor všem vnucovat, nikdo na to není zvědavý. Co takhle místo nadávání napsat vlastní článek o GIS v MySQL, jenomže toho byste asi nebyl schopen soudě podle vašeho projevu.

Jáchym Čepický

Tohle ale není článek o GIS v MS SQL. To je o ničem ;-)

jos


Několik dobře míněných rad pro vytváření databází

Na co se často zapomíná u popisu jak vytvořit databázi, je, jak ji navrhnout. Nečiním si nárok zde popsat teorii relačních databází, ale spíše se jedná o dobře míněné rady, které jsou často ignorovány


mám taky dobře míněný rady

nejdřív jenom pro autora článku:

  • místo screenshotů ManagementStudia bych dodal DDL dotazy, klikat tabulky ve formulářích je krutost, tos mohl rovnou připojit nějaký to .chm
  • Pokud neděláte relace mezi souvisejícími tabulkami WTF? nepleť hlavu čtenářům touhle terminologií – anglicky relation, česky relace, česky v matematice množina, česky v SQL databázích tabulka nebo pohled. to co ty tady popisuješ je anglicky relationship, z důvodu nejednoznačnosti je v češtině lepší používat výhradně termín cizí klíč
  • Nečiním si nárok zde popsat teorii relačních databází – vůbec radši nepoužívej takový silný výrazivo, jak je vidno z příkládku s procedurou (hlavně z uvozujícího textu je v podstatě identická s prací s klasickým SQL) vůbec teorii relačních databází nerozumíš, zkus začít zde

pro ostatní:

  • identity nepoužívat, mssql má už od verze 2005 (nikoliv v express edici, to je jen převlečenej Access) datovej typ uniqueidentifier (RTFM)
  • pokud se nechcete omrdat neustálým používním iconv jen kvůli tomu, že v microsoftím driveru pro php nejde nastavit výstupní kódování, použijte FreeTDS (používáme pro připojení k SQL 2005, .dll zde)
  • MSSQL nepoužívat, pokud to de. v korporátní sféře se dá pochopit, že člověk příde k projektu nad mssql, v ostatních případech je tu postgres
Laďa

Z přiložených zdrojů jsem si vyrobil SQL tabulky a ty jsem chtěl využít v reportu (reporting services). ČR je však o 90 st. otočena. Netušíte, jak to spravit?
Děkuji

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.