<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://zine.net.pl/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Marek Adamczuk</title><link>http://zine.net.pl/blogs/mad/default.aspx</link><description /><dc:language /><generator>CommunityServer 2.1 SP2 (Build: 61129.2)</generator><item><title>Konkurs – autonumerator bez dziur</title><link>http://zine.net.pl/blogs/mad/archive/2009/07/17/konkurs-autonumerator-bez-dziur.aspx</link><pubDate>Fri, 17 Jul 2009 05:25:18 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:4024</guid><dc:creator>mad</dc:creator><slash:comments>2</slash:comments><comments>http://zine.net.pl/blogs/mad/comments/4024.aspx</comments><wfw:commentRss>http://zine.net.pl/blogs/mad/commentrss.aspx?PostID=4024</wfw:commentRss><description>&lt;p&gt;Wczoraj na &lt;a title="http://www.wss.pl/frmThread.aspx?tid=67788" href="http://www.wss.pl/frmThread.aspx?tid=67788"&gt;http://www.wss.pl/frmThread.aspx?tid=67788&lt;/a&gt; zaproponowałem nowy konkurs. Zapraszam wszystkich do zmierzenia się z tematem.&lt;/p&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=4024" width="1" height="1"&gt;</description></item><item><title>Równoległość jobów w SQL Server Agent</title><link>http://zine.net.pl/blogs/mad/archive/2009/07/09/r-wnoleg-o-job-w-w-sql-server-agent.aspx</link><pubDate>Thu, 09 Jul 2009 08:03:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:4003</guid><dc:creator>mad</dc:creator><slash:comments>1</slash:comments><comments>http://zine.net.pl/blogs/mad/comments/4003.aspx</comments><wfw:commentRss>http://zine.net.pl/blogs/mad/commentrss.aspx?PostID=4003</wfw:commentRss><description>&lt;p&gt;W ostatnim czasie ćwiczyłem się trochę zrównoleglanie zadań. Uruchamiałem jednocześnie kolejne części zadania jako joby SQL Server Agenta, spodziewając się skrócenia całościowego czasu wykonania. Pierwsze wyniki były oczywiście niezadawalające – ogólny czas wykonania zadania wzrósł. Gdy zacząłem szukać przyczyny problemu, okazało się że z 50 jednocześnie uruchomionych zadań wystartowało tylko 40. Pozostałe 10 oczekiwało na zakończenie poprzednich – dawało się to łatwo zaobserwować na historii jobów. 10 z nich po prostu startowało później o kilka sekund niezależnie od tego, jak proste było zadanie. &lt;/p&gt;  &lt;p&gt;Zacząłem szukać, gdzie można przestawić ten parametr. Niestety w interfejsie SSMS tego nie znalazłem. Okazało się jednak, że parametr istnieje i nawet jest opisany w bazie wiedzy. Artykuł dotyczy wprawdzie SQL Server 2000, ale na szczęście jest też wzmianka, gdzie funckjonalność przewędrowała na SQL Server 2005. Otóż, parametr ten trafił do tabeli syssubsystems bazy msdb. Co ciekawe, żeby go przestawić, trzeba najzwyczajniej na świecie tabelę tę zupdate’ować. O tak: &lt;/p&gt;  &lt;p&gt;UPDATE msdb.dbo.syssubsystems SET max_worker_threads = 50 WHERE subsystem = 'TSQL'; &lt;/p&gt;  &lt;p&gt;W czasach, w których odwykliśmy już na dobre od update’owania tabel systemowych wygląda to niepokojąco, ale działa. Wystarczy już tylko restart usługi SQL Server Agent i 50 równoległych zadań przestaje być problemem. Dla Agenta oczywiście – sam SQL to zupełnie inna historia. Do opowiedzenia kolejnym razem…&lt;/p&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=4003" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/mad/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/max_5F00_worker_5F00_threads/default.aspx">max_worker_threads</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/Job/default.aspx">Job</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/Agent/default.aspx">Agent</category></item><item><title>MVP</title><link>http://zine.net.pl/blogs/mad/archive/2009/07/03/mvp.aspx</link><pubDate>Fri, 03 Jul 2009 18:14:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:3972</guid><dc:creator>mad</dc:creator><slash:comments>3</slash:comments><comments>http://zine.net.pl/blogs/mad/comments/3972.aspx</comments><wfw:commentRss>http://zine.net.pl/blogs/mad/commentrss.aspx?PostID=3972</wfw:commentRss><description>&lt;p&gt;3 dni temu wraz z Ziemkiem Borowskim, Jackiem Doktórem i Pawłem Pławiakiem zostałem nominowany przez Microsoft do nagrody MVP. &lt;/p&gt;  &lt;p&gt;Choć pewne znaki na Niebie i Ziemi wskazywały, że coś się kroi, to jednak nagroda jest dla mnie jakimś zaskoczeniem. Jest mi bardzo miło. Dopiero oswajam się z myślą, że to się stało. &lt;/p&gt;  &lt;p&gt;Obdarowanemu wypada podziękować. W pierwszej kolejności, rzecz jasna, darczyńcy. Dziękuję zatem korporacji Microsoft za przyznanie mi tej nagrody. Patrząc na moje dokonania w zestawieniu z obecnymi MVP traktuję ją jako mocną zachętę do większego zaangażowania. Tak, tak. Wiem, że MVP nic nie musi. Ale może :). I to chyba znacznie więcej niż sprzed nominacji. &lt;/p&gt;  &lt;p&gt;Składając podziękowania korporacji nie zapominam, za co ona przyznaje ten zaszczytny tytuł. Mianowicie za dzielenie się swoją wiedzą ze Społecznością. Dziękuję Wam, przedstawiciele Społeczności Microsoft, którzy macie ochotę dyskutować ze mna na &lt;a href="http://www.wss.pl/frmThreads.aspx?gid=17" target="_blank"&gt;forum wss.pl&lt;/a&gt; i zaglądać na moje sesje &lt;a href="http://www.ms-groups.pl/plssug/default.aspx" target="_blank"&gt;PLSSUG&lt;/a&gt;. Nie mam wątpliwości, że ta nagroda jest efektem Waszego wielkiego wsparcia, którego niejednokrotnie z Waszej strony doświadczyłem. Dziękuję serdecznie – to bardzo doładowuje.&lt;/p&gt;  &lt;p&gt;And at last, but not least chciałbym podziękować komuś osobiście. A mianowicie mojemu przyjacielowi, a zarazem renominowanemu MVP - &lt;a href="http://zine.net.pl/blogs/sqlgeek" target="_blank"&gt;Pawłowi Potasińskiemu&lt;/a&gt;. Pawle, gdyby nie Ty, mój udział w życiu Społeczności byłby niewspółmiernie mniejszy niż jest. To dzięki Twojej pasji i ogromnej wiedzy przekonałem się do regularnego pisania, a potem moderacji wss.pl. To Ty namówiłeś mnie do prowadzenia sesji na PLSSUG, C2C czy MTS, czy wreszcie do założenia niniejszego bloga. Wreszcie to w ogromnej mierze dzięki Twojemu osobistemu zaangażowaniu, dziś mogę cieszyć się statusem MVP. Czasami wręcz zastanawiam się czyja składowa zaangażowania w tytuł dla mnie była większa: moja własna, czy Twoja. Bez Ciebie pewnie nigdy nie przekonałbym się, że udział w życiu Społeczności to naprawdę fajna przygoda i niesamowite źródło wiedzy. Twój entuzjazm naprawdę zaraża. Jesteś Wielki – dzięki jeszcze raz.&lt;/p&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=3972" width="1" height="1"&gt;</description></item><item><title>ORDER BY - tylko w view</title><link>http://zine.net.pl/blogs/mad/archive/2009/01/13/order-by-tylko-w-view.aspx</link><pubDate>Tue, 13 Jan 2009 13:10:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:2740</guid><dc:creator>mad</dc:creator><slash:comments>2</slash:comments><comments>http://zine.net.pl/blogs/mad/comments/2740.aspx</comments><wfw:commentRss>http://zine.net.pl/blogs/mad/commentrss.aspx?PostID=2740</wfw:commentRss><description>&lt;P&gt;Wszem i wobec wiadomo, że klauzula ORDER BY w view jest niedozwolona. W końcu view to "wirtualna tabela" i jako taka sama z siebie nie ma kolejności rekordów. Sytuacja zmieniła się z nadejściem SQL Server 7.0 i klauzulą TOP. Wtedy bowiem klauzula ORDER BY uzyskała znaczenie części filtra TOP. Oczywiście zdolność sortowania view niejako przy okazji pozostała, co wielu wykorzystywało do obchodzenia problemu nieobsługiwania ORDER BY. Ale to dłuższy temat...&lt;/P&gt;
&lt;P&gt;Tymczasem ostatnio natrafiłem na ciekawy przypadek, gdzie do zastosowania ORDER BY paradoksalnie konieczne okazało się użycie view.&lt;/P&gt;
&lt;P&gt;Wyobraźmy sobie, że chcemy wyświetlić z tabeli&amp;nbsp;widoku systemowych 10 pierwszych i 10 ostatnich obiektów. Na pierwszy rzut oka nic prostrzego:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;top&lt;/span&gt; (10) name &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; sys.objects &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;order&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;by&lt;/span&gt; name&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;union&lt;/span&gt; &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;all&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;top&lt;/span&gt; (10) name &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; sys.objects &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;order&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;by&lt;/span&gt; name &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;desc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A tu okazuje się, że niestety taka składnia nie jest obsługiwana.&amp;nbsp;UNION dopuszcza tylko globalny ORDER BY zapominając jakoby, że w połączeniu z TOP staje się filtrem. Okazuje się jednak, że problem daje się obejść przez zastosowanie VIEW.&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;view&lt;/span&gt; dbo.vwObiektyTrocheZPoczatkuIZKonca&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;as&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;top&lt;/span&gt; (10) name &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; sys.objects &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;order&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;by&lt;/span&gt; name&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;union&lt;/span&gt; &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;all&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;top&lt;/span&gt; (10) name &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; sys.objects &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;order&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;by&lt;/span&gt; name &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;desc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Ten widok założy się bez problemu i będzie działał zgodnie z oczekiwaniami.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=2740" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/mad/archive/tags/SQL/default.aspx">SQL</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/T-SQL/default.aspx">T-SQL</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/TSQL/default.aspx">TSQL</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/view/default.aspx">view</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/order+by/default.aspx">order by</category></item><item><title>Limit 8060 bajtów na wiersz odszedł inaczej</title><link>http://zine.net.pl/blogs/mad/archive/2008/08/30/limit-8060-bajt-w-na-wiersz-odszed-inaczej.aspx</link><pubDate>Sat, 30 Aug 2008 19:44:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1858</guid><dc:creator>mad</dc:creator><slash:comments>0</slash:comments><comments>http://zine.net.pl/blogs/mad/comments/1858.aspx</comments><wfw:commentRss>http://zine.net.pl/blogs/mad/commentrss.aspx?PostID=1858</wfw:commentRss><description>&lt;P&gt;Jedną z istotnych nowości w SQL Server 2005 było zniesienie limitu 8060 bajtów zapisanych w jednym wierszu. Oto krótki test.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; dbo.temp_duzaTabela ( &lt;br /&gt;    a &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(8000), &lt;br /&gt;    b &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(8000), &lt;br /&gt;    c &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(8000) &lt;br /&gt;    )&lt;br /&gt;&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;insert&lt;/span&gt; dbo.temp_duzaTabela (a,b,c) &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; &lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;replicate&lt;/span&gt;(&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'x'&lt;/span&gt;,8000),&lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;replicate&lt;/span&gt;(&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'x'&lt;/span&gt;,8000),&lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;replicate&lt;/span&gt;(&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'x'&lt;/span&gt;,8000)&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Na SQL Server 2000 pierwszy batch generował ostrzeżenie, a drugi błąd. Na SQL Server 2005 oba przechodzą bez problemu. Czy zatem limit 8060 bajtów odszedł? Niestety nie do końca. Spróbujmy tego samego z kolumnami typu char.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; dbo.temp_duzaTabela ( &lt;br /&gt;    a &lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;char&lt;/span&gt;(8000), &lt;br /&gt;    b &lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;char&lt;/span&gt;(8000), &lt;br /&gt;    c &lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;char&lt;/span&gt;(8000) &lt;br /&gt;    )&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Próba wykonania tego batcha ku mojemu zdziwieniu skończyła się komunikatem:&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#ff0000&gt;Msg 1701, Level 16, State 1, Line 1 &lt;BR&gt;Creating or altering table 'temp_duzaTabela' failed because the minimum row size would be 24007, including 7 bytes of internal overhead. This exceeds the maximum allowable table row size of 8060 bytes.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Chwila uparczywego wpatrywania się w komunikat obnaża problem. Kluczowe jest tu słówko minimum. Zatem dla minimalnej wielkości wiersza limit wciąż obowiązuje.&amp;nbsp;Problem rozwiązuje w jakiejś mierze&amp;nbsp;SQL Server 2008 w tej kwestii bynajmniej nie wprowadza żadnej nowej jakości.&lt;/P&gt;
&lt;P&gt;Dziękuję Pawłowi Gailardowi za uświadomienie mi tego problemu.&lt;/P&gt;
&lt;P&gt;[01-09-2008] Edycja: Okazuje się, że jednak SQL Server 2008 w jakiś sposób&amp;nbsp;życie nam tu ułatwia. Nie automatycznie, ale jednak.&amp;nbsp;Otóż atrybut SPARSE powoduje, że damy radę założyć tabelę z typami o stałej długości przekraczającymi sumarycznie 8060 bajtów. &lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; dbo.temp_duzaTabela ( &lt;br /&gt;    a &lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;char&lt;/span&gt;(8000) SPARSE, &lt;br /&gt;    b &lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;char&lt;/span&gt;(8000) SPARSE, &lt;br /&gt;    c &lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;char&lt;/span&gt;(8000) SPARSE&lt;br /&gt;    )&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1858" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/mad/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/row+length+limit/default.aspx">row length limit</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/Sparse/default.aspx">Sparse</category></item><item><title>Konkurs - przywrócenie pierwotnej kolejności kolumn tabeli</title><link>http://zine.net.pl/blogs/mad/archive/2008/07/23/konkurs-przywr-cenie-pierwotnej-kolejno-ci-kolumn-tabeli.aspx</link><pubDate>Wed, 23 Jul 2008 19:24:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1608</guid><dc:creator>mad</dc:creator><slash:comments>0</slash:comments><comments>http://zine.net.pl/blogs/mad/comments/1608.aspx</comments><wfw:commentRss>http://zine.net.pl/blogs/mad/commentrss.aspx?PostID=1608</wfw:commentRss><description>&lt;P&gt;Zgodnie z obietnicą ogłaszam konkurs zapowiedziany na wczorajszej sesji PLSSUG. Zadanie polega na przywróceniu pierwotnej kolejności kolumn tabeli po usunięciu i ponownym odtworzeniu kolumny wyliczanej. Np. mamy tabelę:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; dbo.Osoby ( &lt;br /&gt;id &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;br /&gt;Imie &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(50) &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NOT&lt;/span&gt; &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NULL&lt;/span&gt;, &lt;br /&gt;Nazwisko &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(100) &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NOT&lt;/span&gt; &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NULL&lt;/span&gt;, &lt;br /&gt;NazwaPelna &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;as&lt;/span&gt; Imie+&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;' '&lt;/span&gt;+Nazwisko, &lt;br /&gt;TelefonDoPracy &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(30) &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NULL&lt;/span&gt;, &lt;br /&gt;TelefonDomowy &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(30) &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NULL&lt;/span&gt;, &lt;br /&gt;TelefonKom &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(30) &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NULL&lt;/span&gt;, &lt;br /&gt;Telefony &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;as&lt;/span&gt;  &lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;ISNULL&lt;/span&gt;(TelefonDoPracy+&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;';'&lt;/span&gt;,&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;''&lt;/span&gt;)+&lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;ISNULL&lt;/span&gt;(TelefonDomowy+&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;';'&lt;/span&gt;,&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;''&lt;/span&gt;)+&lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;ISNULL&lt;/span&gt;(TelefonKom+&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;';'&lt;/span&gt;,&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;''&lt;/span&gt;),&lt;br /&gt;EMail &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;varchar&lt;/span&gt;(100), &lt;br /&gt;DataRejestracji &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;datetime&lt;/span&gt;&lt;br /&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Po usunięciu i ponownym odtworzeniu kolumn NazwaPelna i Telefony, znajdą się one na końcu listy kolumn tabeli. Słabo napisane aplikacje mogą tej zmiany nie wytrzymać. Dlatego będziemy chcieli przywrócić kolejność pierwotną. &lt;/P&gt;
&lt;P&gt;W czasie sesji pokazałem, jak wygenerować skrypty, które dla dowolnej tabeli:&lt;/P&gt;
&lt;P&gt;1. Zapisze definicję wszystkich kolumn wyliczanych wraz z pierwotną kolejnością do tabeli &lt;BR&gt;2. Usunie wszystkie kolumny wyliczane&amp;nbsp; &lt;BR&gt;3. Odtworzy kolumny wyliczane (lądują na końcu listy)&lt;/P&gt;
&lt;P&gt;Definicja tabeli jest w skrypcie recollate.sql umieszczonych w &lt;A href="http://ms-groups.pl/communities/PLSSUG/Shared%20Documents/Forms/AllItems.aspx?RootFolder=%2fcommunities%2fPLSSUG%2fShared%20Documents%2fSkrypty%20SQL&amp;amp;FolderCTID=&amp;amp;View=%7b94539CEA%2d073B%2d47E6%2dB583%2d3F4E29D67266%7d" target=_blank&gt;zasobach&lt;/A&gt; PLSSUG. Dla wygody zacytuję ją ponownie tutaj.&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; dbo.temp_ComputedCols ( &lt;br /&gt;    TableName &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysname&lt;/span&gt;, &lt;br /&gt;    ColumnName &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysname&lt;/span&gt;, &lt;br /&gt;    definition &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;max&lt;/span&gt;), &lt;br /&gt;    position &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;KEY&lt;/span&gt; (TableName, ColumnName) &lt;br /&gt;    )&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Zadanie konkursowe polega na tym, żeby na podstawie definicji tabeli po operacji usunięcia i odtworzenia kolumn wyliczanych + zawartości tabeli temp_ComputedCols wygenerować skrypt, który doprowadzi tabelę do pierwotnej postaci - wszystkie kolumny są w tej samej kolejności co przed operacją. Linie skryptu mają być wygenerowane w języku TSQL w postaci procedury lub funkcji tabelarycznej. Jako jedyny parametr procedury/funkcji powinna być przekazana nazwa tabeli, dla której generujemy skrypt.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Warunki oceny rozwiązania:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;1. Rozwiązanie nie może spowodować jakiejkolwiek utraty danych w tabeli &lt;BR&gt;2. Rozwiązanie powinno wykonać minimalną liczbę manipulacji na danych i strukturze tabeli &lt;BR&gt;3. Rozwiązanie powinno przewidywać, że jest więcej niż jedna kolumna wyliczana, tak jak w przykładzie &lt;BR&gt;4. Rozwiązanie powinno być możliwie jak najszybsze&lt;/P&gt;
&lt;P&gt;Dla uproszczenia zakładamy, że w chwili rozpoczęcia naprawy na tabeli, którą mamy naprawić nie ma żadnych więzów ani indeksów.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Czekam na rozwiązania konkursowe do końca 15-08-2008 - proszę o przysyłanie ich na mój mail z profilu na wss.pl. Najciekawsze rozwiązania opublikuję, a najlepsze nagrodzę na najbliższym spotkaniu PLSSUG. Do 10.08.2008 będę poza Polską i nie wiem, czy będę miał dostęp do maila, zatem proszę nie zrażać się brakiem mojej reakcji w tym czasie.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Pozdrawiam &lt;BR&gt;Marek Adamczuk&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1608" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/mad/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/TSQL/default.aspx">TSQL</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/konkurs/default.aspx">konkurs</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/Kolumny+wyliczane/default.aspx">Kolumny wyliczane</category></item><item><title>Hash czy małpa a sprawa collation</title><link>http://zine.net.pl/blogs/mad/archive/2008/07/23/hash-czy-ma-pa-a-sprawa-collation.aspx</link><pubDate>Wed, 23 Jul 2008 09:56:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1605</guid><dc:creator>mad</dc:creator><slash:comments>1</slash:comments><comments>http://zine.net.pl/blogs/mad/comments/1605.aspx</comments><wfw:commentRss>http://zine.net.pl/blogs/mad/commentrss.aspx?PostID=1605</wfw:commentRss><description>&lt;P&gt;Wczoraj miałem przyjemność poprowadzić na PLSSUG Warszawa prezentację dotyczącą collation na SQL Serverze. W czasie prezentacji wygłosiłem pewną, nie do końca uprawnioną tezę. Mianowicie stwierdziłem, że collation z którym zakładane są domyślnie kolumny tabeli tymczasowej ustawia się na collation bazy bieżącej w SQL Server 2005 i z collation bazy tempdb w SQL Server 2000. W rzeczywistości jest to prawdą tylko dla zmiennych tablicowych. Oto przykład:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Teal;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;-- ważne, żeby to nie było collation servera!&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;database&lt;/span&gt; bad_db &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;collate&lt;/span&gt; SQL_Polish_CP1250_CI_AS&lt;br /&gt;GO&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;use&lt;/span&gt; bad_db&lt;br /&gt;GO&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;declare&lt;/span&gt; @t &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; (a &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;nvarchar&lt;/span&gt;(128))&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; * &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; @t t &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;join&lt;/span&gt; &lt;span style="color: LawnGreen;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysobjects&lt;/span&gt; o &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;on&lt;/span&gt; t.a = o.name&lt;br /&gt;GO&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; #t (a &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;nvarchar&lt;/span&gt;(128))&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; * &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; #t t &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;join&lt;/span&gt; &lt;span style="color: LawnGreen;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysobjects&lt;/span&gt; o &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;on&lt;/span&gt; t.a = o.name&lt;br /&gt;GO&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Przykład uruchamiamy na SQL Server 2000 i SQL Server 2005. Jak się okazuje, query ze zmienną tablicową wykonuje się prawidłowo tylko na 2005. Wszystkie inne zwracają błąd konfliktu collation. Zatem #tabele tymczasowe w kontekście collation nadal są złe na SQL Server 2005. Co więcej, test przeprowadzony na ostatnim dostępnym mi buildzie SQL Server 2008 daje identyczny rezultat, co 2005.&lt;/P&gt;
&lt;P&gt;Czy zatem, będąc świadomymi zła, jesteśmy w stanie mu zaradzić? Owszem jesteśmy, ale wymaga to zmiany przyzwyczajeń w pisaniu kodu. Otóż, aby być collation insensitive, musimy przy tworzeniu tabel tymczasowych, a na SQL 2000 również zmiennych tablicowych, dopisywać przy stringowych kolumnach klauzulę COLLATE database_default. Na naszym przykładzie wygląda to tak:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Teal;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;-- tak już nie musimy robić na SQL Server 2005 i wyższych&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;declare&lt;/span&gt; @t &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; (a &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;nvarchar&lt;/span&gt;(128) &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;collate&lt;/span&gt; database_default)&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; * &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; @t t &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;join&lt;/span&gt; &lt;span style="color: LawnGreen;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysobjects&lt;/span&gt; o &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;on&lt;/span&gt; t.a = o.name&lt;br /&gt;GO&lt;br /&gt;&lt;span style="color: Teal;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;-- tak niestety musimy nadal&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; #t (a &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;nvarchar&lt;/span&gt;(128) &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;collate&lt;/span&gt; database_default)&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; * &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; #t t &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;join&lt;/span&gt; &lt;span style="color: LawnGreen;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysobjects&lt;/span&gt; o &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;on&lt;/span&gt; t.a = o.name&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;drop&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; #t&lt;br /&gt;GO&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Wnioski&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Jeśli nie chcemy mieć potencjalnego konfliktu collation: &lt;BR&gt;1. Dopisujemy collate database_default przy definicjach kolumn stringowych #tabel tymczasowych zawsze i zmiennych @tablicowych na SQL 2000. &lt;BR&gt;2. Jeśli mamy SQL 2005 i nie chcemy wyrabiać sobie odruchu z punktu 1 - bardziej lubimy @tabele niż #tabele. Abstrahując od innych warunków ich zastosowania, rzecz jasna.&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1605" width="1" height="1"&gt;</description><category domain="http://zine.net.pl/blogs/mad/archive/tags/SQL/default.aspx">SQL</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/Tabela+tymczasowa/default.aspx">Tabela tymczasowa</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/Collation/default.aspx">Collation</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/zmienna+tablicowa/default.aspx">zmienna tablicowa</category><category domain="http://zine.net.pl/blogs/mad/archive/tags/T-SQL/default.aspx">T-SQL</category></item><item><title>Obsługa wyjątków na SQL - (nie) daj się złapać</title><link>http://zine.net.pl/blogs/mad/archive/2008/07/07/obs-uga-wyj-tk-w-na-sql-daj-si-z-apa.aspx</link><pubDate>Mon, 07 Jul 2008 20:59:00 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1442</guid><dc:creator>mad</dc:creator><slash:comments>4</slash:comments><comments>http://zine.net.pl/blogs/mad/comments/1442.aspx</comments><wfw:commentRss>http://zine.net.pl/blogs/mad/commentrss.aspx?PostID=1442</wfw:commentRss><description>&lt;P&gt;Będzie trochę o obsłudze wyjątków na SQL Server. O tym, kiedy może okazać się przydatna i jakie czyhają pułapki. A będzie na przykładzie. Otóż mamy sytuację, w której musimy na chwilę zdropić sporą ilość obiektów proceduralnych na bazie danych, aby je po wykonaniu pewnej operacji odtworzyć. Po co? O tym za następnym razem. Dziś skupię się na zawiłościach dropienia i odtwarzania obiektów. Dla uproszczenia wywodu przyjmijmy, że wszystkie interesujące nas obiekty należą do schematu dbo i są procedurami, widokami, funkcjami TSQL wszelkiej maści lub triggerami. Przyjmijmy też, że nazwy obiektów podlegających naszej operacji mamy w następującej tabeli:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;create&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;table&lt;/span&gt; dbo.ObjectsToRecreate (&lt;br /&gt;  ObjectName &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysname&lt;/span&gt; &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NOT&lt;/span&gt; &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NULL&lt;/span&gt;,&lt;br /&gt;  ObjectDefinition &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysname&lt;/span&gt; &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NULL&lt;/span&gt;,&lt;br /&gt;  ObjectId &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;NULL&lt;/span&gt;,&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;CONSTRAINT&lt;/span&gt; PK_ObjectsToRecreate &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;KEY&lt;/span&gt; (ObjectName))&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Aby było co odtwarzać po zdropieniu - zapiszmy sobie definicje obiektów do naszej tabeli. Z SQL Server 2005 sprawa jest prosta - używamy nowej, fajnej funkcji object_definition. &lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;update&lt;/span&gt; ObjectsToRecreate &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;SET&lt;/span&gt; ObjectDefinition = OBJECT_DEFINITION(&lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;OBJECT_ID&lt;/span&gt;(ObjectName))&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Kiedy już mamy kopię treści ciał obiektów możemy zabrać się do dropienia. O ile obiekty nie są użyte w innych z klauzulą SCHEMABINDING, tudzież w niskopoziomowych obiektach takich jak defaulty, checki czy kolumny wyliczalne - operacja powinna pójść bezproblemowo. Jak? Sprawę załatwi kawałek dynamicznego SQL-a.&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;declare&lt;/span&gt; @sql &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;max&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; @sql = N&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;''&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; @sql = @sql +N&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'drop '&lt;/span&gt;+ &lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;case&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;when&lt;/span&gt; o.type &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;in&lt;/span&gt; (&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'IF'&lt;/span&gt;,&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'TF'&lt;/span&gt;,&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'FN'&lt;/span&gt;) &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; N&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'function '&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;when&lt;/span&gt; o.type = &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'P'&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; N&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'procedure '&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;when&lt;/span&gt; o.type = &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'V'&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; N&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'view '&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;when&lt;/span&gt; o.type = &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'TR'&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; N&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'trigger '&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;end&lt;/span&gt; +schema_name(o.schema_id)+N&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;'.'&lt;/span&gt;+&lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;quotename&lt;/span&gt;(o.name)+N&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;';'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; dbo.objectsToRecreate otr&lt;br /&gt;&lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;join&lt;/span&gt; sys.objects o &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;on&lt;/span&gt; otr.ObjectName = o.name&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;exec&lt;/span&gt; (@sql)&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Teraz śmiało wykonujemy naszą operację, której przeszkadzałyby zdropione obiekty i zabieramy się do ich odtworzenia. Tym razem raczej nie obejdzie się bez kursora. Nie wydaje się on na pierwszy rzut oka czymś specjalnie trudnym:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;declare&lt;/span&gt; @definition &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;max&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;declare&lt;/span&gt; c &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;cursor&lt;/span&gt; local static read_only forward_only&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;for&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; ObjectDefinition &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; dbo.objectsToRecreate&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;open&lt;/span&gt; c&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;fetch&lt;/span&gt; next &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; c &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;into&lt;/span&gt; @definition&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;while&lt;/span&gt; &lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@@fetch_status&lt;/span&gt; = 0 &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;begin&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;exec&lt;/span&gt; (@definition)&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;fetch&lt;/span&gt; next &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; c &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;into&lt;/span&gt; @definition  &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;close&lt;/span&gt; c &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;deallocate&lt;/span&gt; c&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Wszystko zadziała pięknie, o ile usunięte uprzednio obiekty nie będą zależne od siebie. Szczególnie boleśnie możemy to odczuć na widokach i funkcjach. Jeśli nie odtworzymy obiektów we właściwej kolejności – operacja po prostu się nie uda. Pytanie tylko: Jak znaleźć tę właściwą kolejność? Jak się okazuje – pytanie niebanalne. Mamy wprawdzie tabelę sys.sql_dependencies, ale po zdropieniu obiektów pustą, a i przed trudno wciąż jej ufać. Nawet gdy ją mamy porządnie uzupełnioną – rozplątanie właściwej kolejności obiektów w skomplikowanym przypadku wcale nie jest oczywiste. O sys.sql_dependencies napiszę innym razem – to temat na osobny artykuł. Tymczasem jest dużo prostsza metoda na uzyskanie właściwej kolejności. Jednym zdaniem: próbuj odtwarzać obiekty do skutku. Osiągniemy to łatwo obudowując nasz kod pętlą while. Kończymy, gdy uda nam się odtworzyć wszystkie obiekty. Aby nie oglądać paskudnych komunikatów błędów – opakujmy nasz kod bloki obsługi wyjątków:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;declare&lt;/span&gt; @definition &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;max&lt;/span&gt;), @name &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sysname&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;while&lt;/span&gt; &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;exists&lt;/span&gt; (&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; 1 &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; dbo.objectsToRecreate &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;where&lt;/span&gt; objectId &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;is&lt;/span&gt; &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;null&lt;/span&gt;) &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;begin&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;declare&lt;/span&gt; c &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;cursor&lt;/span&gt; local static read_only forward_only&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;for&lt;/span&gt; &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;select&lt;/span&gt; ObjectDefinition, ObjectName &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; dbo.objectsToRecreate &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;where&lt;/span&gt; objectId &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;is&lt;/span&gt; &lt;span style="color: Silver;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;null&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;open&lt;/span&gt; c&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;fetch&lt;/span&gt; next &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; c &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;into&lt;/span&gt; @definition, @name&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;while&lt;/span&gt; &lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@@fetch_status&lt;/span&gt; = 0 &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;begin&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;begin&lt;/span&gt; try&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;exec&lt;/span&gt; (@definition)&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;end&lt;/span&gt; try&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;begin&lt;/span&gt; catch&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;set&lt;/span&gt; @definition = @name+&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;':'&lt;/span&gt;+error_message()&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;print&lt;/span&gt; @definition&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;end&lt;/span&gt; catch&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;update&lt;/span&gt; dbo.objectsToRecreate &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;set&lt;/span&gt; objectId = &lt;span style="color: Fuchsia;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;object_id&lt;/span&gt;(@name) &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;where&lt;/span&gt; ObjectName = @name&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;fetch&lt;/span&gt; next &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;from&lt;/span&gt; c &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;into&lt;/span&gt; @definition, @name  &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;close&lt;/span&gt; c &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;deallocate&lt;/span&gt; c&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Jeśli nasza baza była spójna na moment zdropienia, po kilku iteracjach będziemy mieli prawidłowo odtworzone obiekty. Niestety nasza radość trwa do momentu opakowania w/w kodu w transakcję. Po pierwszym błędzie, każda kolejna próba odtworzenia, prawidłowa lub nie,&amp;nbsp; kończy się komunikatem:&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#ff0000&gt;Msg 3930, Level 16, State 1, Line 18&lt;BR&gt;The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Co gorsza, ten kod nigdy się nie kończy, bo nigdy nie dojdziemy do warunku wyjścia z pętli. I niestety dochodzimy tu do poważnego ograniczenia stosowalności mechanizmu obsługi wyjątków na SQL-u w obecnie dostępnych wersjach. I właśnie z tego powodu w tym miejscu porzuciłem ten mechanizm do rozwiązania bieżącego problemu i dobrałem się do niego w zupełnie inny sposób. Wniosek: jeśli używamy try catch, nie liczmy na to, że uda nam się w tej samej transakcji cokolwiek jeszcze wykonać poza zaprezentowaniem błędu. Musimy być zawsze gotowi na zakończenie transakcji po takiej operacji.&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1442" width="1" height="1"&gt;</description></item><item><title>Pierwszy raz ...</title><link>http://zine.net.pl/blogs/mad/archive/2008/07/07/pierwszy-raz.aspx</link><pubDate>Mon, 07 Jul 2008 20:52:03 GMT</pubDate><guid isPermaLink="false">0de27b5c-4a0c-4e7a-8e19-9d082c99f8a3:1439</guid><dc:creator>mad</dc:creator><slash:comments>8</slash:comments><comments>http://zine.net.pl/blogs/mad/comments/1439.aspx</comments><wfw:commentRss>http://zine.net.pl/blogs/mad/commentrss.aspx?PostID=1439</wfw:commentRss><description>&lt;p&gt;...kiedyś musi być. Do tej pory nie prowadziłem jeszcze bloga i nie mam pojęcia, jak mi to będzie szło. Nam&amp;#243;wiony przez Pawła Potasińskiego skorzystałem z uprzejmości Michała Grzegorzewskiego i postanowiłem spr&amp;#243;bować. Inaczej nigdy się nie przekonam. Będę tu pisał o tym, czym co dzień zaskakuje mnie SQL Server i inne wynalazki świata informatyki. Pierwszy tekst już niebawem.&lt;/p&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1439" width="1" height="1"&gt;</description></item></channel></rss>