niedziela, 8 maja 2011

globalna identyfikacja tabeli tymczasowej

Lokalne tabele tymczasowe  są widoczne tylko dla ich twórców podczas tego samego połączenia z instancją SQL Server na którym zostały utworzone, są usuwane gdy użytkownik odłączy się od instancji.
Tak mniej więcej piszą w BOL, dodatkowo wszyscy wiemy że w ramach tej samej sesji nie można założyć dwóch tabel o takiej samej nazwie.

Niewiadomo jak serwer radzi sobie z rozpoznawaniem, która tabela jest przypisana do którego SPIDu, w skali instancji niepowtarzalność gwarantuje 12 znaków HEX, które są zwiększającym się licznikiem.
Licznik ten zeruje się przy każdym restarcie serwera, ciekawe co się stanie jeżeli w czasie nieprzerwanej pracy serwera założymy więcej niż 281474976710655 tabel tymczasowych, czyli FFFFFFFFFFFF.

Zróbmy sobie mały test

USE tempdb
GO
SELECT @@SPID

CREATE TABLE #a (i INT);
GO
DECLARE @q VARCHAR(max)

SET @q='SELECT @@SPID; CREATE TABLE #a (i INT);
SELECT id ,NAME
FROM  tempdb.sys.sysobjects
WHERE xtype =''U'' AND NAME LIKE ''#a%''
'
EXEC (@q);
GO
SELECT id ,NAME
FROM  tempdb.sys.sysobjects
WHERE xtype ='U' AND NAME like '#a%'

------
55

------
55

id          NAME
----------------------------------
1253579504  #a__...___000000000001
1269579561  #a__...___000000000002

id          NAME
----------------------------------
1253579504  #a__...___000000000001

Prosty test pokazuje, że tabela nie jest niszczona po odłączeniu a może być tez podczas jego trwania i w ramach jednej sesji mogą istnieć tabele o takiej samej nazwie.

sobota, 7 maja 2011

Panie, za czym ta kolejka – 30 lat później

W czwartek, w ramach 54 spotkania grupy PLSSUG miałem okazję stanąć przed karkołomną operacją opowiedzenia o statystykach oczekiwania w ciągu 90 minut, bardzo wszystkich przepraszam za to, że nie zmieściłem się w wyznaczonym czasie ;)
Temat jest bardzo ciekawy i jednocześnie bardzo rozległy, dotykający chyba wszystkich obszarów dotyczących SQL Server.
Jeżeli ktoś jest zainteresowany załączam materiały i czekam na dodatkowe pytania;)

sobota, 9 kwietnia 2011

management studio draw II

Zgodnie z komentarzami narysowałem szachownicę (numeracja jest odwrotna )


Z prawidłową numeracją




Ktoś chętny do pisania logiki ;)

Kod nie jest zbyt orginalny




CREATE TABLE #szachownica (id INT IDENTITY(1,1) PRIMARY KEY,
                                         A NCHAR(5),B NCHAR(5), C NCHAR(5) ,D NCHAR(5),E NCHAR(5), F NCHAR(5), G NCHAR(5), H NCHAR(5))
 DECLARE @i INT=8286
 DECLARE @t INT=8286
                                        
INSERT #szachownica
VALUES
(NCHAR(9820),NCHAR(@t)+NCHAR(9822)+NCHAR(@t),NCHAR(9821),NCHAR(@t)+NCHAR(9819)+NCHAR(@t),NCHAR(9818),NCHAR(@t)+NCHAR(9821)+NCHAR(@t),NCHAR(9822),NCHAR(@t)+NCHAR(9820)+NCHAR(@t)),
(NCHAR(@t)+NCHAR(9823)+NCHAR(@t),NCHAR(9823),NCHAR(@t)+NCHAR(9823)+NCHAR(@t),NCHAR(9823),NCHAR(@t)+NCHAR(9823)+NCHAR(@t),NCHAR(9823),NCHAR(@t)+NCHAR(9823)+NCHAR(@t),NCHAR(9823)),
('',REPLICATE(NCHAR(@i),5),'',REPLICATE(NCHAR(@i),5),'',REPLICATE(NCHAR(@i),5),'',REPLICATE(NCHAR(@i),5)),
(REPLICATE(NCHAR(@i),5),'',REPLICATE(NCHAR(@i),5),'',REPLICATE(NCHAR(@i),5),'',REPLICATE(NCHAR(@i),5),''),
('',REPLICATE(NCHAR(@i),5),'',REPLICATE(NCHAR(@i),5),'',REPLICATE(NCHAR(@i),5),'',REPLICATE(NCHAR(@i),5)),
(REPLICATE(NCHAR(@i),5),'',REPLICATE(NCHAR(@i),5),'',REPLICATE(NCHAR(@i),5),'',REPLICATE(NCHAR(@i),5),''),
(NCHAR(9817),NCHAR(@t)+NCHAR(9817)+NCHAR(@t),NCHAR(9817),NCHAR(@t)+NCHAR(9817)+NCHAR(@t),NCHAR(9817),NCHAR(@t)+NCHAR(9817)+NCHAR(@t),NCHAR(9817),NCHAR(@t)+NCHAR(9817)+NCHAR(@t)),
(NCHAR(@t)+NCHAR(9814)+NCHAR(@t),NCHAR(9816),NCHAR(@t)+NCHAR(9815)+NCHAR(@t),NCHAR(9813),NCHAR(@t)+NCHAR(9812)+NCHAR(@t),NCHAR(9815),NCHAR(@t)+NCHAR(9816)+NCHAR(@t),NCHAR(9814))


SELECT
Row_Number() OVER (ORDER BY id desc) AS [⁞⁞],
A,B,C,D,E,F,G,H FROM #szachownica
ORDER BY id

Na potrzeby pisania kodu warto zmienić generowanie szachownicy i przetrzymywanie pozycji figur.
Lepiej też zrezygnować z kolorowania samej szachownicy.


CREATE TABLE #szachownica (id INT IDENTITY(1,1) PRIMARY KEY,
                                         A int, B int, C int ,D int,E int, F int, G int, H int)
                                        
INSERT #szachownica
VALUES
(9820,9822,9821,9819,9818,9821,9822,9820),
(9823,9823,9823,9823,9823,9823,9823,9823),
(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(9817,9817,9817,9817,9817,9817,9817,9817),
(9814,9816,9815,9813,9812,9815,9816,9814)


SELECT
id AS[*],
ISNULL(NCHAR(A),'') AS A,
ISNULL(NCHAR(B),'') AS B,
ISNULL(NCHAR(C),'') AS C,
ISNULL(NCHAR(D),'') AS D,
ISNULL(NCHAR(E),'') AS E,
ISNULL(NCHAR(F),'') AS F,
ISNULL(NCHAR(G),'') AS G,
ISNULL(NCHAR(H),'') AS H
FROM #szachownica
ORDER BY id DESC


Procedura pozwalająca na poruszanie się po planszy


CREATE PROC #ruch @st CHAR(2),@no CHAR(2)
AS
DECLARE @sl CHAR(1),@sc INT,@nl CHAR(1),@nc INT,@sup VARCHAR(MAX)

SELECT @sl=LEFT(@st,1),@sc=RIGHT(@st,1),@nl=LEFT(@no,1),@nc=RIGHT(@no,1)

SET @sup ='UPDATE #szachownica
SET '+@nl+' = (SELECT CAST('+@sl+' AS CHAR(4)) FROM #szachownica WHERE id ='+CAST(@sc AS CHAR(1))+')
WHERE id ='+CAST(@nc AS CHAR(1))
EXEC(@sup)

SET @sup ='UPDATE #szachownica
SET '+@sl+' = NULL
WHERE id ='+CAST(@sc AS CHAR(1))
EXEC(@sup)

SELECT
id AS[*],
ISNULL(NCHAR(A),'') AS A,
ISNULL(NCHAR(B),'') AS B,
ISNULL(NCHAR(C),'') AS C,
ISNULL(NCHAR(D),'') AS D,
ISNULL(NCHAR(E),'') AS E,
ISNULL(NCHAR(F),'') AS F,
ISNULL(NCHAR(G),'') AS G,
ISNULL(NCHAR(H),'') AS H
FROM #szachownica
ORDER BY id DESC

I najszybsza rozgrywka


EXECUTE #ruch 'F2','F4'
EXECUTE #ruch 'E7','E6'
EXECUTE #ruch 'G2','G4'
EXECUTE #ruch 'D8','H4'






piątek, 8 kwietnia 2011

management studio draw

Wyświetlanie wyników w Microsoft SQL Server  Management Studio jest nastawione na wydajność nie ma w nim możliwości zabawy z kolorami (pomijając błędy J) czy zróżnicowaniem czcionek i tak powinno być.
Od graficznego przedstawiania wyników są inne narzędzia, chociażby Reporting Services.
Ale jak ktoś się uprze to można się pobawić w SSMS.

CREATE TABLE #ranking (dzien VARCHAR(100), wynik INT)

INSERT #ranking
VALUES  ('Poniedziałek',87),('Wtorek',57),('Środa',30),('Czwartek',28),('Piątek',38),('Sobota',11),('Niedziela',0)
GO

Robimy sobie ranking

SELECT
Row_Number() OVER (ORDER BY wynik desc) AS miejsce,
r.dzien,r.wynik
FROM #ranking r
ORDER BY wynik DESC



Jest, no ale jakiś taki nie przemawiający do wyobraźni, no to go trochę zmodyfikujmy

SELECT
NCHAR(9311+Row_Number() OVER (ORDER BY wynik desc)) AS miejsce,
r.dzien,r.wynik,
REPLICATE(NCHAR(9608), 100. * r.wynik / t.razem) AS graf
FROM #ranking r,
(SELECT SUM(wynik) razem FROM #ranking)  t
ORDER BY wynik DESC



Prawda, że ładniej

(update : do komentarza Pawła Potasińskiego)

 

UPDATE #ranking
SET wynik =157
WHERE dzien ='Poniedziałek'
GO
SELECT
NCHAR(9311+Row_Number() OVER (ORDER BY wynik desc)) AS miejsce,
r.dzien,r.wynik,
REPLICATE(NCHAR(9608), 100. * r.wynik / t.razem) AS graf,
100. * r.wynik / t.razem AS [100. * r.wynik / t.razem]
FROM #ranking r,
(SELECT SUM(wynik) razem FROM #ranking)  t
ORDER BY wynik DESC


Można też inaczej
SELECT
NCHAR(10101+Row_Number() OVER (ORDER BY wynik desc)) AS miejsce,
r.dzien,r.wynik,
REPLICATE(NCHAR(
CASE  WHEN 100. * r.wynik/t.razem = 0 THEN 0
            WHEN 100. * r.wynik/t.razem > 0 AND 100. * r.wynik/t.razem < 10 THEN 9617 
            WHEN 100. * r.wynik/t.razem > 10 AND 100. * r.wynik/t.razem < 20 THEN 9618
            WHEN 100. * r.wynik/t.razem > 20 AND 100. * r.wynik/t.razem < 30 THEN 9619
            WHEN 100. * r.wynik/t.razem > 30  THEN 9608 END ),  20) AS graf
FROM #ranking r,
(SELECT SUM(wynik) razem FROM #ranking) t
ORDER BY wynik DESC




Tabelka z kontaktami

CREATE TABLE #osoby (nazwisko VARCHAR(100),imie VARCHAR(100),plec char(1), kontakt VARCHAR(500),aktywny BIT)

INSERT #osoby
VALUES ('Kowalski','Jan','M','+48 22 123-45-78',1),
('Malinowski','Stefan','M','mstefan@serwer.pl',1),
('Nowak','Zofia','F','+48 600-123-234',1),
('Kowalik','Barbara','F','bkowal@host.com',0)

Wyświetlamy wynik

SELECT * FROM #osoby



Nudno, bez wyrazu trochę zmienimy

SELECT nazwisko,imie,
[płeć]=CASE plec WHEN 'F'THEN NCHAR(9792) WHEN 'M'THEN NCHAR(9794) ELSE ''END,
kontakt =CASE  WHEN kontakt LIKE '+%'THEN NCHAR(9742)+kontakt WHEN kontakt LIKE '%@%.%'THEN  NCHAR(9993)+kontakt END,
aktywny= CASE aktywny WHEN 1 THEN NCHAR(9745) ELSE NCHAR(9744) END
FROM #osoby



Podoba się ?
Oczywiście trzeba takie „malowanie „ traktować w kategorii zabawy i nie stosować tego w zapytaniach, unikać zbędnych kosztów w planach. Od takich fantazji są inne narzędzia.