Databáze 2011/2012 T-SQL - kurzry, funkce RNDr.David Hksza, Ph.D. http://siret.cz/hksza
Osnva T-SQL kurzry T-SQL funkce Cvičení
Kurzr Datvá struktura umžňující pracvat s výsledkem dtazu Smyslem kurzru je přemsti prpast mezi jazykem SQL, který je mnžinvě rientvaný a prcedurálními (OO) jazyky (C, C++, C#, Java, ) knverze tabulkvé struktury na mdel sekvenčníh subru Kurzr je v pdstatě emulace magnetické pásky
Pstup práce s kurzrem DECLARE deklarace kurzru specifikace SELECTu, jehž result set chceme prcházet OPEN tevření kurzru a načtení dat specifikvaných v DECLARE části FETCH CLOSE načtení záznamu z kurzru, tj. řádku výsledku děje se typicky v cyklu zavření kurzru z kurzru nelze dále číst pmcí FETCH, ale struktura v paměti stále existuje lze následně vlat znvu OPEN DEALLOCATE dealkace všech dat spjených s kurzrem
Příklad pužití kurzru DECLARE curprductprice CURSOR FOR SELECT pc.name, SUM(p.ListPrice) AS SumPrice FROM SalesLT.Prduct p JOIN SalesLT.PrductCategry pc ON (p.prductcategryid = pc.prductcategryid) GROUP BY pc.name; DECLARE @Name VARCHAR(50), @SumPrice REAL; OPEN curprductprice; FETCH NEXT FROM curprductprice INTO @Name, @SumPrice; WHILE @@FETCH_STATUS = 0 IF @SumPrice > 50000 PRINT @Name; FETCH NEXT FROM curprductprice INTO @Name, @SumPrice; CLOSE curprductprice; DEALLOCATE curprductprice;
Typy kurzrů DECLARE cursr_name CURSOR [typ] FOR select_statement [fr_update_klauzule] LOCAL GLOBAL SCROLL defaultně je kurzr GLOBAL, tj. jeh živtnst trvá i p uknčení dávky LOCAL zajistí autmaticku dealkaci kurzru při uknčení dávky (např. prcedury) umžňuje phybvat se v kurzru v libvlném směru libvlný pčet řádků parametry FETCH - FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE FOR UPDATE [OF clumn_name [,...n]] definuje aktualizvatelné slupce (nejsu-li žádné definvané, pak lze aktualizvat libvlný slupec)
Příklad pužití SCROLL kurzru DECLARE curprductprice CURSOR SCROLL FOR SELECT pc.name, SUM(p.ListPrice) AS SumPrice FROM SalesLT.Prduct p JOIN SalesLT.PrductCategry pc ON (p.prductcategryid = pc.prductcategryid) GROUP BY pc.name; DECLARE @Name VARCHAR(50), @SumPrice REAL; OPEN curprductprice; FETCH LAST FROM curprductprice INTO @Name, @SumPrice; WHILE @@FETCH_STATUS = 0 IF @SumPrice > 50000 PRINT @Name; FETCH PRIOR FROM curprductprice INTO @Name, @SumPrice; CLOSE curprductprice; DEALLOCATE curprductprice;
Funkce v T-SQL Uživatelsky definvané funkce (user-defined functin - UDF) umžňují na rzdíl d prcedur vracet libvlný datvý typ (včetně tabulky) Nelze vlat nedeterministické funkce, tj. funkce vracející různé výsledky při vlání se stejnu sadu vstupních parametrů (RAND, GETDATE, ) Zdrj funkce T-SQL CLR (Cmmn Language Runtime) C#, VB.NT, Typy Skalární funkce vracejí skalární hdntu, tj. NE mnžinu (INT, REAL, VARCHAR(n), ) Tabulkvé funkce vracejí tabulku s kteru lze pracvat ve FROM části SELECT klauzule Pužití v SELECT příkazech, v jiných UDF, V CHECK IO, vždy je třeba při vlání UDF (na rzdíl d systémvých funkcí) uvádět schéma
Skalární funkce IF OBJECT_ID('udfExpensiveCategries') IS NOT NULL DROP FUNCTION udfexpensivecategries; CREATE FUNCTION udfexpensivecategries(@minprice INT) RETURNS VARCHAR(MAX) AS DECLARE @rv VARCHAR(MAX) = ''; DECLARE curprductprice CURSOR FOR SELECT pc.name, SUM(p.ListPrice) AS SumPrice FROM SalesLT.Prduct p JOIN SalesLT.PrductCategry pc ON (p.prductcategryid = pc.prductcategryid) GROUP BY pc.name; DECLARE @Name VARCHAR(50), @SumPrice REAL; OPEN curprductprice; FETCH NEXT FROM curprductprice INTO @Name, @SumPrice; WHILE @@FETCH_STATUS = 0 IF @SumPrice > @minprice IF @rv!= '' SET @rv = @rv+'; '; SET @rv = @rv + @Name; FETCH NEXT FROM curprductprice INTO @Name, @SumPrice; CLOSE curprductprice; DEALLOCATE curprductprice; RETURN @rv; SELECT db.udfexpensivecategries(5000)
Inline tabulkvé funkce IF OBJECT_ID('udfExpensiveCategriesTab') IS NOT NULL DROP FUNCTION udfexpensivecategriestab; CREATE FUNCTION udfexpensivecategriestab(@minprice INT) RETURNS TABLE AS RETURN ( SELECT pc.name, SUM(p.ListPrice) AS SumPrice FROM SalesLT.Prduct p JOIN SalesLT.PrductCategry pc ON (p.prductcategryid = pc.prductcategryid) GROUP BY pc.name HAVING SUM(p.ListPrice) > @minprice); SELECT * FROM db.udfexpensivecategriestab(50000)
Multi-statement tabulkvé funkce IF OBJECT_ID('udfExpensiveCategriesTabExt') IS NOT NULL DROP FUNCTION udfexpensivecategriestabext; CREATE FUNCTION udfexpensivecategriestabext(@value INT, @cnt INT) RETURNS @rvtab TABLE (cl1 INT, cl2 INT) AS DECLARE @i INT = 1; WHILE @i <= @cnt INSERT INTO @rvtab VALUES (@value+@i, @value+@i+1); SET @i = @i + 1; RETURN; SELECT * FROM db.udfexpensivecategriestabext(10, 7);