<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;AkICRn85eip7ImA9WhVTEU8.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546</id><updated>2012-02-25T01:09:27.122+01:00</updated><category term="xml" /><category term="ISNUMERIC" /><category term="CLR" /><category term="Pivot" /><category term="Transakcje" /><category term="SQL Server 2008" /><category term="XSL" /><category term="import xml" /><category term="stored procedure" /><category term="MCP" /><category term="Integralność danych" /><category term="postback" /><category term="rozmiar indeksów" /><category term="ASP.NET" /><category term="SSMS" /><category term="duplikaty" /><category term="DDL" /><category term="EVENTTARGET" /><category term="DML" /><category term="70-441" /><category term="rozmiar tabel" /><category term="sql" /><category term="plany zapytań" /><category term="MCITP" /><category term="row_number" /><category term="DMV" /><category term="ograniczenia" /><category term="Dynamiczny SQL" /><category term="dobre praktyki" /><category term="indeksy" /><category term="T-SQL" /><category term="EVENTARGUMENT" /><category term="sqlxml" /><category term="optymalizacja" /><category term="cte" /><title>SQL Blog</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://updatedev.blogspot.com/" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>23</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/UpdateDev" /><feedburner:info uri="updatedev" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D0IFSHwzfCp7ImA9WhVTEU8.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-8018977389238826129</id><published>2012-02-24T01:36:00.001+01:00</published><updated>2012-02-25T00:18:39.284+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-25T00:18:39.284+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="EVENTTARGET" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET" /><category scheme="http://www.blogger.com/atom/ns#" term="postback" /><category scheme="http://www.blogger.com/atom/ns#" term="EVENTARGUMENT" /><title>EVENTARGUMENT, EVENTTARGET i postback w ASP.NET</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/3PNj_9YoiAdtK594_UVeVLPRpTI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3PNj_9YoiAdtK594_UVeVLPRpTI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/3PNj_9YoiAdtK594_UVeVLPRpTI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3PNj_9YoiAdtK594_UVeVLPRpTI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Dzisiaj wyjatkowo poruszę temat nie związany z SQL-em.&lt;br /&gt;
W ASP.NET do obslugi postback wykorzystywane są dwa ukryte pola na formularzu oraz funkcja javascript. Problem polega na tym , że ASP.NET generuje domyślnie ten kod tylko w przypadku gdy na formularzu występuje kontrolka, która tego wymaga. Może to być np. LinkButton, TextBox, CheckBox, DropDownList (właściwość AutoPostBack musi być ustawiona na true).&lt;br /&gt;
W przypadku gdy powyższe jest spełnione to podglądając kod HTML zobaczymy następujący kod&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;input&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="hidden"&lt;/span&gt; &lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;="__EVENTTARGET"&lt;/span&gt; &lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="__EVENTTARGET"&lt;/span&gt; &lt;span style="color: red;"&gt;value&lt;/span&gt;&lt;span style="color: blue;"&gt;=""&lt;/span&gt; &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;input&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="hidden"&lt;/span&gt; &lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;="__EVENTARGUMENT"&lt;/span&gt; &lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="__EVENTARGUMENT"&lt;/span&gt; &lt;span style="color: red;"&gt;value&lt;/span&gt;&lt;span style="color: blue;"&gt;=""&lt;/span&gt; &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;script&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/javascript"&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: green;"&gt;//&amp;lt;![CDATA[&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;var&lt;/span&gt; theForm = document.forms[&lt;span style="color: #006080;"&gt;'Form1'&lt;/span&gt;];&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (!theForm) {&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     theForm = document.Form1;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt; &lt;span style="color: blue;"&gt;function&lt;/span&gt; __doPostBack(eventTarget, eventArgument) {&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;     &lt;span style="color: blue;"&gt;if&lt;/span&gt; (!theForm.onsubmit || (theForm.onsubmit() != &lt;span style="color: blue;"&gt;false&lt;/span&gt;)) {&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;         theForm.__EVENTTARGET.value = eventTarget;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;         theForm.__EVENTARGUMENT.value = eventArgument;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;         theForm.submit();&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;     }&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt; &lt;span style="color: green;"&gt;//]]&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;script&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Niestety powyższe nie jest generowane przez kontrolki Button i ImageButton.&lt;br /&gt;
&lt;br /&gt;
W przypadku gdy z jakiegoś powodu jest to wymagane to wtedy trzeba sobie radzić w inny sposób i np w funkcji Page_Load dopisać kod, który doda powyższe dwie ukryte kontrolki jak również javascript.&lt;br /&gt;
&lt;br /&gt;
Przykład implementacji takiego rozwiązania można jest np &lt;a href="http://www.codeproject.com/Articles/12422/How-to-know-which-HTML-object-was-clicked"&gt;tutaj&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Dlaczego o tym pisze? A to dlatego, że miałem cały dzień zepsuty przez to, że ktoś próbował wykorzystać EVENTARGUMENT w funkcji, która obługiwała zdarzenie OnClick dla ImageButton.&lt;br /&gt;
&lt;br /&gt;
Wszystko byłoby w porządku, pod warunkiem gdy kod ten nie nadawał się do thedailywtf.com.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-8018977389238826129?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/2ZCalh_NEXQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/8018977389238826129/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=8018977389238826129" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/8018977389238826129?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/8018977389238826129?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/2ZCalh_NEXQ/eventargument-eventtarget-i-postback-w.html" title="EVENTARGUMENT, EVENTTARGET i postback w ASP.NET" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2012/02/eventargument-eventtarget-i-postback-w.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEER3g7fSp7ImA9WhRaFkU.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-6638108966686830191</id><published>2012-02-19T22:22:00.001+01:00</published><updated>2012-02-19T22:23:26.605+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-19T22:23:26.605+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="optymalizacja" /><category scheme="http://www.blogger.com/atom/ns#" term="Integralność danych" /><title>Bez kluczy, bez indeksów</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/OJUCcuVLsrY1n9cC2LEj9tjmTKE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/OJUCcuVLsrY1n9cC2LEj9tjmTKE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/OJUCcuVLsrY1n9cC2LEj9tjmTKE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/OJUCcuVLsrY1n9cC2LEj9tjmTKE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;a href="http://updatedev.blogspot.com/2012/02/ograniczenia-w-bazie-danych.html" title="Ograniczenia w bazie danych"&gt;Poprzedni post&lt;/a&gt; dotyczący ograniczeń w bazie danych zakończyłem planem wykonania prostego zapytania aktualizującego jeden rekord w tabeli. Na planie tym pojawiło się 13 operacji w tym skanowanie indeksu. Niewątpliwie wszystkie ograniczenia, o których pisałem są bardzo przydatne i w 99% procentach przypadków mają one zastosowanie.&lt;br /&gt;
&lt;br /&gt;
Pozostaje ten 1% kiedy optymalizacja zapisu jest bardziej istotna od integralności. Przykładem takim może być zapisywanie statystyk dostępu do serwisu internetowego. W przypadku dużej liczby odwiedzin, gdyby była potrzeba zapisania informacji o każdej sesji, czy czynności wykonanych przez użytkownika opercje zapisywania danych statystycznych mogłyby mieć negatywny wpływ na podstawową funkcjonalność.&lt;br /&gt;
Dane ta bardzo często w środowki produkcyjnym były by tylko danymi do zapisu a odczyt następowałby tylko w sytuacji importowania do jakiegoś magazynu danych. Choć i ta operacja mogłaby być robiona z kopi zapasowej. Oczywiście taka sytuacja miałaby miejce w przypadku zastosowania tylko jednej bazy danych. Alternatywą może być np osobna baza tylko dla danych statystycznych.&lt;br /&gt;
&lt;br /&gt;
Tak więc o ile integralność danych jest bardzo często aspektem kluczowym, warto także na uwadze optymalizację.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-6638108966686830191?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/lnpDjRKpSgM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/6638108966686830191/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=6638108966686830191" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/6638108966686830191?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/6638108966686830191?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/lnpDjRKpSgM/bez-kluczy-bez-indeksow.html" title="Bez kluczy, bez indeksów" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2012/02/bez-kluczy-bez-indeksow.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEGQnY_fyp7ImA9WhRaFkU.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-4505337524368977348</id><published>2012-02-17T00:21:00.001+01:00</published><updated>2012-02-19T22:23:43.847+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-19T22:23:43.847+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="plany zapytań" /><category scheme="http://www.blogger.com/atom/ns#" term="ograniczenia" /><category scheme="http://www.blogger.com/atom/ns#" term="optymalizacja" /><category scheme="http://www.blogger.com/atom/ns#" term="Integralność danych" /><title>Ograniczenia w bazie danych</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7U_0PC75z5r-U025ChLUF4LLH9I/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7U_0PC75z5r-U025ChLUF4LLH9I/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7U_0PC75z5r-U025ChLUF4LLH9I/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7U_0PC75z5r-U025ChLUF4LLH9I/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Ograniczenia w bazie danych są najlepszym sposobem na zachowanie &lt;a href="http://updatedev.blogspot.com/2011/09/intregralnosc-danych-i-wartosci-null.html"&gt;integralności danych&lt;/a&gt;. SQL Server oferuje kilka różnych typów ograniczeń i koszt ich użycia nie jest taki sam. Ograniczenia sprawdzane są w określonej kolejności. W poniższych testach zademonstruje działanie kilku z nich.&lt;br /&gt;
Przykładowe zapytania bądą wykonywane na bazie danych, do której skrypt można pobrać z &lt;a href="https://docs.google.com/open?id=0B2UUe2ybqbzINjNhZmIyN2QtZjg5Mi00Mjg1LWIxZWQtYzkyMDA5NWNmNzRm"&gt;tej&lt;/a&gt; lokalizacji.&lt;br /&gt;
Poniższy skrypt doda wyzwalacz, który będzie potrzebny do wykonania jednego z testów. Wszystkie testy będą wykonane na tabeli Subdivision.&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;CREATE&lt;/span&gt; &lt;span style="color: blue;"&gt;TRIGGER&lt;/span&gt; TRIG_SUBDIVISION_UPDATE &lt;span style="color: blue;"&gt;ON&lt;/span&gt; Subdivision&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;AFTER&lt;/span&gt; &lt;span style="color: blue;"&gt;UPDATE&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;AS&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt; &lt;span style="color: blue;"&gt;IF&lt;/span&gt; &lt;span style="color: blue;"&gt;EXISTS&lt;/span&gt;(&lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; inserted &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; SubdivisionId &lt;span style="color: blue;"&gt;like&lt;/span&gt; &lt;span style="color: #006080;"&gt;'XX-%'&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     &lt;span style="color: blue;"&gt;RAISERROR&lt;/span&gt;(&lt;span style="color: #006080;"&gt;'Invalid SubdivisionId'&lt;/span&gt;, 1,16)&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt; GO&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Poniżej dla przejrzystości deklaracja tabeli Subdivision. Znajduję się ona także w skrypcie, o którym wspomniałem wcześniej.&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;IF&lt;/span&gt; &lt;span style="color: blue;"&gt;NOT&lt;/span&gt; &lt;span style="color: blue;"&gt;EXISTS&lt;/span&gt;(&lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; SYS.tables &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; name = &lt;span style="color: #006080;"&gt;'Subdivision'&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;CREATE&lt;/span&gt; &lt;span style="color: blue;"&gt;TABLE&lt;/span&gt; Subdivision(&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;     SubdivisionID &lt;span style="color: blue;"&gt;varchar&lt;/span&gt;(6) &lt;span style="color: blue;"&gt;NOT&lt;/span&gt; &lt;span style="color: blue;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     SubdivisionName nvarchar(50) &lt;span style="color: blue;"&gt;NOT&lt;/span&gt; &lt;span style="color: blue;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     CountryID  &lt;span style="color: blue;"&gt;AS&lt;/span&gt; &lt;span style="color: blue;"&gt;CAST&lt;/span&gt;(&lt;span style="color: blue;"&gt;LEFT&lt;/span&gt;(SubdivisionID,(2)) &lt;span style="color: blue;"&gt;AS&lt;/span&gt; &lt;span style="color: blue;"&gt;CHAR&lt;/span&gt;(2)) PERSISTED,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     &lt;span style="color: blue;"&gt;Constraint&lt;/span&gt; FK_Subdivisions_Country &lt;span style="color: blue;"&gt;FOREIGN&lt;/span&gt; &lt;span style="color: blue;"&gt;KEY&lt;/span&gt;(CountryID) &lt;span style="color: blue;"&gt;REFERENCES&lt;/span&gt; Country(CountryID),&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;     &lt;span style="color: blue;"&gt;Constraint&lt;/span&gt; PK_Subdivision &lt;span style="color: blue;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color: blue;"&gt;KEY&lt;/span&gt;(SubdivisionID),&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;     &lt;span style="color: blue;"&gt;Constraint&lt;/span&gt; SubdivisionLength &lt;span style="color: blue;"&gt;CHECK&lt;/span&gt;(LEN(SubdivisionID) &amp;gt;= 4)&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt; GO&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Istotnym elementów testów jest tabela Hotel&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: blue;"&gt;exists&lt;/span&gt;(&lt;span style="color: blue;"&gt;select&lt;/span&gt; * &lt;span style="color: blue;"&gt;from&lt;/span&gt; sys.tables &lt;span style="color: blue;"&gt;where&lt;/span&gt; name = &lt;span style="color: #006080;"&gt;'Hotel'&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;create&lt;/span&gt; &lt;span style="color: blue;"&gt;table&lt;/span&gt; Hotel (&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;     HotelID &lt;span style="color: blue;"&gt;int&lt;/span&gt; &lt;span style="color: blue;"&gt;identity&lt;/span&gt; &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: blue;"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     Name nvarchar(100) &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: blue;"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     Address1 nvarchar(100) &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: blue;"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     Address2 nvarchar(100) &lt;span style="color: blue;"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;     City nvarchar(255) &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: blue;"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;     SubdivisionID &lt;span style="color: blue;"&gt;varchar&lt;/span&gt;(6) &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: blue;"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;     Postcode &lt;span style="color: blue;"&gt;varchar&lt;/span&gt;(10) &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: blue;"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;     &lt;span style="color: blue;"&gt;constraint&lt;/span&gt; PK_Hotel &lt;span style="color: blue;"&gt;primary&lt;/span&gt; &lt;span style="color: blue;"&gt;key&lt;/span&gt;(HotelID),&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;     &lt;span style="color: blue;"&gt;constraint&lt;/span&gt; FK_Hotel_Subdivision &lt;span style="color: blue;"&gt;foreign&lt;/span&gt; &lt;span style="color: blue;"&gt;key&lt;/span&gt;(SubdivisionID) &lt;span style="color: blue;"&gt;references&lt;/span&gt; Subdivision (SubdivisionID)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt; go&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;



&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;



Kolejności sprawdzania ograniczeń&lt;/h2&gt;
Ograniczenia w bazie sprawdzane są w następującej kolejności&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Wartości domyślne&lt;/li&gt;
&lt;li&gt;Wartość NULL&lt;/li&gt;
&lt;li&gt;Ograniczenie CHECK&lt;/li&gt;
&lt;li&gt;Klucze obce w tabelach zależnych&lt;/li&gt;
&lt;li&gt;Klucze tabeli aktualizowanej&lt;/li&gt;
&lt;li&gt;Klucz podstawowy / wartość unikalna&lt;/li&gt;
&lt;li&gt;Wyzwalacze&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;



&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;



Sprawdzanie wartości NULL&lt;/h2&gt;
W testach pominę pierwszy typ ograniczeń. Osobiście rzadko korzystam z tej funkcjonalności i staram się przenosić ustawianie wartości domyślnych do aplikacji bądź procedur składowych.&lt;br /&gt;
&lt;br /&gt;
Sprawdzanie wartości NULL a raczej NOT NULL jest jednym z moich ulubionych. Ja lubie dane, a jeżeli tych danych nie ma w połowie tabeli to kolumna może powinna zostać przenesiona do innej tabeli.&lt;br /&gt;
&lt;br /&gt;
Kolumna SubdivisionId będąca kluczem podstawowym nie może przyjmować wartości NULL.&lt;br /&gt;
&lt;br /&gt;
Wykonując poniższą kwerendę w wynikach pojawi się błąd.&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;BEGIN&lt;/span&gt; &lt;span style="color: blue;"&gt;TRAN&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;UPDATE&lt;/span&gt; Subdivision &lt;span style="color: blue;"&gt;SET&lt;/span&gt; SubdivisionId = &lt;span style="color: blue;"&gt;NULL&lt;/span&gt; &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; SubdivisionName = &lt;span style="color: #006080;"&gt;'York'&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;ROLLBACK&lt;/span&gt; TRAN&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style="color: red; font-family: Courier New;"&gt;Msg 515, Level 16, State 2, Line 2&lt;br /&gt;    &lt;br /&gt;Cannot insert the value NULL into column 'SubdivisionID', table 'SQLTest.dbo.Subdivision'; column does not allow nulls. UPDATE fails.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Warto zwrócić uwagę tutaj na fakt, że sprawdzane jest ograniczenie sprawdzające czy nowa wartością nie jest NULL a nie klucz podstawowy.&lt;br /&gt;
&lt;h2&gt;



&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;



Organiczenie CHECK&lt;/h2&gt;
Jest to prawdopodobnie jedno z rzadziej używanych ograniczeń w bazie danych, jednakże jest ono bardzo przydatne w kontekście optymalizacji bazy danych.&lt;br /&gt;
&lt;br /&gt;
W przypadku kodów ISO dla jednostek administracyjnych, pierwsze dwie litery to jest oznaczenie państwa po którym następuje myślnik i kod właściwy jednostki administracyjnej. W przykładzie tym w tabeli Subdivision jest ograniczenie na minimalną długość tekstu, która musi wynosić 4 znaki.&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;BEGIN&lt;/span&gt; &lt;span style="color: blue;"&gt;TRAN&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;UPDATE&lt;/span&gt; Subdivision &lt;span style="color: blue;"&gt;SET&lt;/span&gt; SubdivisionId = &lt;span style="color: #006080;"&gt;'XX-'&lt;/span&gt; &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; SubdivisionName = &lt;span style="color: #006080;"&gt;'York'&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;ROLLBACK&lt;/span&gt; TRAN&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Powyższe zapytanie zwróci następujący błąd:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: red; font-family: Courier New;"&gt;Msg 547, Level 16, State 0, Line 2&lt;br /&gt;    &lt;br /&gt;The UPDATE statement conflicted with the CHECK constraint "SubdivisionLength". The conflict occurred in database "SQLTest", table "dbo.Subdivision", column 'SubdivisionID'.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Ograniczenie to, podobnie jak wartość domyślna i NOT NULL jest ograniczeniem własnym tabeli. Nie występują tutaj żadne odwołania do innych obiektów. Warto zwrócić tutaj uwagę na kolejność sprawdzania ograniczeń. Pomimo tego, że w tabeli Hotel istnieje rekord dla GB-YOR, który jest aktualizowany przez powyższe zapytanie, klucz obcy nie jest weryfikowany.&lt;br /&gt;
&lt;h2&gt;



&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;



Sprawdzanie kluczy obcych w tabelach zależnych&lt;/h2&gt;
W nastepnej kolejności sprawdzane są klucze obce&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;BEGIN&lt;/span&gt; &lt;span style="color: blue;"&gt;TRAN&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;UPDATE&lt;/span&gt; Subdivision &lt;span style="color: blue;"&gt;SET&lt;/span&gt; SubdivisionId = &lt;span style="color: #006080;"&gt;'XX-ZZ'&lt;/span&gt; &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; SubdivisionName = &lt;span style="color: #006080;"&gt;'York'&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;ROLLBACK&lt;/span&gt; TRAN&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Powyższe zapytanie, gdy zakończylo się sukcesem spowodowałoby utratę integralności danych. Z racji tego, że w tabeli Hotel znajduję się klucz obcy zapytanie to zwróci następujący błąd&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: red; font-family: Courier New;"&gt;Msg 547, Level 16, State 0, Line 2&lt;br /&gt;    &lt;br /&gt;The UPDATE statement conflicted with the REFERENCE constraint "FK_Hotel_Subdivision". The conflict occurred in database "SQLTest", table "dbo.Hotel", column 'SubdivisionID'.&lt;/span&gt;&lt;br /&gt;
&lt;h2&gt;



&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;



Sprawdzanie kluczy obcych w tabeli aktualizowanej&lt;/h2&gt;
Aby przeprowadzic kolejny test najpier będzie trzeba zaktualizować tabelę Hotel. W tym celu klucz obcy do tabeli Subdivision będzie musiał zostać tymczasowo wyłączony.&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;BEGIN&lt;/span&gt; &lt;span style="color: blue;"&gt;TRAN&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;ALTER&lt;/span&gt; &lt;span style="color: blue;"&gt;TABLE&lt;/span&gt; Hotel &lt;span style="color: blue;"&gt;NOCHECK&lt;/span&gt; &lt;span style="color: blue;"&gt;CONSTRAINT&lt;/span&gt; FK_Hotel_Subdivision&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;UPDATE&lt;/span&gt; Hotel &lt;span style="color: blue;"&gt;SET&lt;/span&gt; Subdivisionid = &lt;span style="color: #006080;"&gt;'XX-ZZ'&lt;/span&gt; &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; HotelId=1&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;ALTER&lt;/span&gt; &lt;span style="color: blue;"&gt;TABLE&lt;/span&gt; Hotel &lt;span style="color: blue;"&gt;CHECK&lt;/span&gt; &lt;span style="color: blue;"&gt;CONSTRAINT&lt;/span&gt; FK_Hotel_Subdivision&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt; &lt;span style="color: blue;"&gt;UPDATE&lt;/span&gt; Subdivision &lt;span style="color: blue;"&gt;SET&lt;/span&gt; SubdivisionId = &lt;span style="color: #006080;"&gt;'XX-ZZ'&lt;/span&gt; &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; SubdivisionName = &lt;span style="color: #006080;"&gt;'York'&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt; &lt;span style="color: blue;"&gt;ROLLBACK&lt;/span&gt; TRAN&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Powyższe zapytanie aktualizujące tabelę Subdivision jest takie samo jak w poprzednim teście, jednakże tym razem zwrócony zostanie następujący błąd:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: red; font-family: Courier New;"&gt;Msg 547, Level 16, State 0, Line 6&lt;br /&gt;    &lt;br /&gt;The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_Subdivisions_Country". The conflict occurred in database "SQLTest", table "dbo.Country", column 'CountryID'.&lt;/span&gt;&lt;br /&gt;
&lt;h2&gt;



&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;



Sprawdzanie kluczy podstawowych, wartości unikalnych&lt;/h2&gt;
Przetestowanie sprawdzanie kluczy podstawowych w tabeli Subdivision, przy jednoczesnym zachowaniu sekwencji testów jest niemożliwe.&lt;br /&gt;
&lt;h2&gt;



&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;



Wyzwalacze&lt;/h2&gt;
Ostatnim etapem weryfikacji danych i sprawdzania integralności wbudowanej w SQL Server są wyzwalacze.&lt;br /&gt;
&lt;br /&gt;
W calu wykonania tego testu najpierw trzeba wykonać poniże zapytanie, które spraw, że nie pojawi się błąd związany z kluczami obcymi.&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; INSERT &lt;span style="color: blue;"&gt;INTO&lt;/span&gt; Country &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'XX'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'Dummy'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'XXX'&lt;/span&gt;, 0&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; GO&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Teraz ponownie wykonując następujące zapytanie zostanie uruchomiony wyzwalacz&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;BEGIN&lt;/span&gt; &lt;span style="color: blue;"&gt;TRAN&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;ALTER&lt;/span&gt; &lt;span style="color: blue;"&gt;TABLE&lt;/span&gt; Hotel &lt;span style="color: blue;"&gt;NOCHECK&lt;/span&gt; &lt;span style="color: blue;"&gt;CONSTRAINT&lt;/span&gt; FK_Hotel_Subdivision&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;UPDATE&lt;/span&gt; Hotel &lt;span style="color: blue;"&gt;SET&lt;/span&gt; Subdivisionid = &lt;span style="color: #006080;"&gt;'XX-ZZ'&lt;/span&gt; &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; HotelId=1&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;ALTER&lt;/span&gt; &lt;span style="color: blue;"&gt;TABLE&lt;/span&gt; Hotel &lt;span style="color: blue;"&gt;CHECK&lt;/span&gt; &lt;span style="color: blue;"&gt;CONSTRAINT&lt;/span&gt; FK_Hotel_Subdivision&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt; &lt;span style="color: blue;"&gt;UPDATE&lt;/span&gt; Subdivision &lt;span style="color: blue;"&gt;SET&lt;/span&gt; SubdivisionId = &lt;span style="color: #006080;"&gt;'XX-ZZ'&lt;/span&gt; &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; SubdivisionName = &lt;span style="color: #006080;"&gt;'York'&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt; &lt;span style="color: blue;"&gt;ROLLBACK&lt;/span&gt; TRAN&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Sprawdza on czy nowa wartość zaczyna się od XX i jeżeli tak jest zwrócony jest błąd.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="color: red;"&gt;
Invalid SubdivisionId&lt;br /&gt;
Msg 50000, Level 1, State 16&lt;/div&gt;
&lt;br /&gt;
Powyższe przykłady pokazały kolejność sprawdzania ograniczeń w bazie danych.&lt;br /&gt;
&lt;br /&gt;
Powyższe rozważania zakończę planem wykonania zapytania aktualizującego dane w tabeli Subdivision. Proste zapytanie a operacji jest nie tak mało. Na planie można między innymi zauważyć kolejność sprawdzania kluczy obcych.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://lh6.ggpht.com/-ROu53XDxvj8/Tz2PilkGE_I/AAAAAAAAADw/SWp60Cfw4mE/s1600-h/OgraniczeniaPlanWykonania%25255B7%25255D.png"&gt;&lt;img alt="OgraniczeniaPlanWykonania" border="0" height="108" src="http://lh3.ggpht.com/-4tFufQwEZKM/Tz2PjtGfj6I/AAAAAAAAAD4/7dTE2JPmPL0/OgraniczeniaPlanWykonania_thumb%25255B5%25255D.png?imgmax=800" style="border-color: -moz-use-text-color; border-style: none; border-width: 0px; display: inline;" title="OgraniczeniaPlanWykonania" width="604" /&gt;&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
Dalsze rozwzania na temat powyższego planu pozostawie sobie na kolejny post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-4505337524368977348?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/trYy98omOZk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/4505337524368977348/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=4505337524368977348" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/4505337524368977348?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/4505337524368977348?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/trYy98omOZk/ograniczenia-w-bazie-danych.html" title="Ograniczenia w bazie danych" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-4tFufQwEZKM/Tz2PjtGfj6I/AAAAAAAAAD4/7dTE2JPmPL0/s72-c/OgraniczeniaPlanWykonania_thumb%25255B5%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2012/02/ograniczenia-w-bazie-danych.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUER348fSp7ImA9WhRaE0Q.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-4163990447246783425</id><published>2012-02-09T20:00:00.000+01:00</published><updated>2012-02-16T14:16:46.075+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-16T14:16:46.075+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rozmiar tabel" /><category scheme="http://www.blogger.com/atom/ns#" term="DMV" /><category scheme="http://www.blogger.com/atom/ns#" term="indeksy" /><category scheme="http://www.blogger.com/atom/ns#" term="rozmiar indeksów" /><title>Rozmiar tabel i indeksów w bazie danych</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9lg6I6nziBBYo5uJQY33EKR2Fgk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9lg6I6nziBBYo5uJQY33EKR2Fgk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9lg6I6nziBBYo5uJQY33EKR2Fgk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9lg6I6nziBBYo5uJQY33EKR2Fgk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Ostatnio zajmowałem się projektem strony, która hostowana jest na serwerze, gdzie nie było pełnej kontroli nad serwerem baz danych. Jednym z wymagań była możliwość monitorowania wielkości bazy danych. SQL Server umożliwia wykonanie tego zadania poprzez odpytywanie widoków systemowych. Wszystkie dane jakie były potrzebe do wykonania tego zadania znajdują się w 4 widokach.  &lt;br /&gt;
Poniżej znajduję się skrypt i trochę przykładowych danych do testowania.  &lt;br /&gt;
&lt;div class="csharpcode"&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;create&lt;/span&gt; &lt;span style="color: blue;"&gt;database&lt;/span&gt; MyTest   &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; go &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;



Baza danych lotnisk&lt;/h2&gt;
&lt;a href="https://docs.google.com/open?id=0B2UUe2ybqbzIYjk1NWQ3ZTgtMzg0MS00NjA3LWFiMTgtNzQ1MzBlYTlkMGY5" title="Baza danych lotnisk w SQL"&gt;Tutaj&lt;/a&gt; możecie pobrać bazę danych lotnisk. Skrypt SQL został stworzony na podstawie bazy, którą można pobrac z &lt;a href="http://www.partow.net/miscellaneous/airportdatabase/#DatabaseStructure"&gt;tej&lt;/a&gt; lokalizacji. Lista nie jest aktualna i nie ma np. na niej lotniska w Warszawa-Modlin.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;




Baza danych państw&lt;/h2&gt;
&lt;a href="https://docs.google.com/open?id=0B2UUe2ybqbzIMmJiMzk4ZDAtZjVjZC00ZjQ5LWIzYzAtZTg2MmQxOTBlYTFk" title="Baza danych państw w SQL"&gt;Tutaj&lt;/a&gt; możecie pobrać bazę danych państw. Została ona stworzona na podstawie &lt;a href="http://en.wikipedia.org/wiki/ISO_3166-1"&gt;tego&lt;/a&gt; arykułu. &lt;br /&gt;
&lt;br /&gt;
Po odpaleniu wcześniej wspomnianych skryptów w bazie danych pojawią się dwie nowe tabele.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;




Sprawzdanie rozmiaru tabel i indeksów&lt;/h2&gt;
I teraz odpalając poniższy skrypt uzyskamy rozmiar obiektów w bazie.&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;DECLARE&lt;/span&gt; @TABLENAME &lt;span style="color: blue;"&gt;VARCHAR&lt;/span&gt;(126)   &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;SET&lt;/span&gt; @TABLENAME = &lt;span style="color: blue;"&gt;NULL&lt;/span&gt;   &lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     TABLE_NAME,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     INDEX_NAME,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;     TYPE_DESC,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;     INDEX_ID,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;     PARTITION_NUMBER,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;     RESERVED_PAGES * 8 &lt;span style="color: blue;"&gt;AS&lt;/span&gt; RESERVED_SPACE,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;     USED_PAGES * 8 &lt;span style="color: blue;"&gt;AS&lt;/span&gt; USED_SPACE,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;     DATA_PAGES * 8 &lt;span style="color: blue;"&gt;AS&lt;/span&gt; &lt;span style="color: blue;"&gt;DATA&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt;     &lt;span style="color: blue;"&gt;ROWS&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt;     &lt;span style="color: blue;"&gt;SUM&lt;/span&gt;(RESERVED_PAGES * 8) &lt;span style="color: blue;"&gt;OVER&lt;/span&gt; (PARTITION &lt;span style="color: blue;"&gt;BY&lt;/span&gt; TABLE_NAME) &lt;span style="color: blue;"&gt;AS&lt;/span&gt; TOTAL_SPACE_RESERVED,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum15" style="color: #606060;"&gt;  15:&lt;/span&gt;     &lt;span style="color: blue;"&gt;SUM&lt;/span&gt;(RESERVED_PAGES * 8) &lt;span style="color: blue;"&gt;OVER&lt;/span&gt; (PARTITION &lt;span style="color: blue;"&gt;BY&lt;/span&gt; TABLE_NAME) - &lt;span style="color: blue;"&gt;SUM&lt;/span&gt;(USED_PAGES * 8) &lt;span style="color: blue;"&gt;OVER&lt;/span&gt; (PARTITION &lt;span style="color: blue;"&gt;BY&lt;/span&gt; TABLE_NAME) &lt;span style="color: blue;"&gt;AS&lt;/span&gt; TOTAL_SPACE_UNUSED&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum16" style="color: #606060;"&gt;  16:&lt;/span&gt; &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; (&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum17" style="color: #606060;"&gt;  17:&lt;/span&gt;     &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum18" style="color: #606060;"&gt;  18:&lt;/span&gt;         T.NAME &lt;span style="color: blue;"&gt;AS&lt;/span&gt; TABLE_NAME,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum19" style="color: #606060;"&gt;  19:&lt;/span&gt;         I.NAME &lt;span style="color: blue;"&gt;AS&lt;/span&gt; INDEX_NAME,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum20" style="color: #606060;"&gt;  20:&lt;/span&gt;         I.TYPE_DESC,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum21" style="color: #606060;"&gt;  21:&lt;/span&gt;         I.INDEX_ID,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum22" style="color: #606060;"&gt;  22:&lt;/span&gt;         P.PARTITION_NUMBER,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum23" style="color: #606060;"&gt;  23:&lt;/span&gt;         &lt;span style="color: blue;"&gt;SUM&lt;/span&gt;(PS.RESERVED_PAGE_COUNT) &lt;span style="color: blue;"&gt;AS&lt;/span&gt; RESERVED_PAGES,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum24" style="color: #606060;"&gt;  24:&lt;/span&gt;         &lt;span style="color: blue;"&gt;SUM&lt;/span&gt;(PS.USED_PAGE_COUNT) &lt;span style="color: blue;"&gt;AS&lt;/span&gt; USED_PAGES,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum25" style="color: #606060;"&gt;  25:&lt;/span&gt;         &lt;span style="color: blue;"&gt;SUM&lt;/span&gt;(&lt;span style="color: blue;"&gt;CASE&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum26" style="color: #606060;"&gt;  26:&lt;/span&gt;             &lt;span style="color: blue;"&gt;WHEN&lt;/span&gt; (PS.INDEX_ID &amp;lt; 2) &lt;span style="color: blue;"&gt;THEN&lt;/span&gt; (IN_ROW_DATA_PAGE_COUNT + LOB_USED_PAGE_COUNT + ROW_OVERFLOW_USED_PAGE_COUNT)&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum27" style="color: #606060;"&gt;  27:&lt;/span&gt;             &lt;span style="color: blue;"&gt;ELSE&lt;/span&gt; LOB_USED_PAGE_COUNT + ROW_OVERFLOW_USED_PAGE_COUNT&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum28" style="color: #606060;"&gt;  28:&lt;/span&gt;         &lt;span style="color: blue;"&gt;END&lt;/span&gt;) &lt;span style="color: blue;"&gt;AS&lt;/span&gt; DATA_PAGES,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum29" style="color: #606060;"&gt;  29:&lt;/span&gt;         &lt;span style="color: blue;"&gt;SUM&lt;/span&gt; (&lt;span style="color: blue;"&gt;CASE&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum30" style="color: #606060;"&gt;  30:&lt;/span&gt;                 &lt;span style="color: blue;"&gt;WHEN&lt;/span&gt; (PS.INDEX_ID &amp;lt; 2) &lt;span style="color: blue;"&gt;THEN&lt;/span&gt; PS.ROW_COUNT&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum31" style="color: #606060;"&gt;  31:&lt;/span&gt;                 &lt;span style="color: blue;"&gt;ELSE&lt;/span&gt; 0&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum32" style="color: #606060;"&gt;  32:&lt;/span&gt;             &lt;span style="color: blue;"&gt;END&lt;/span&gt;) &lt;span style="color: blue;"&gt;AS&lt;/span&gt; &lt;span style="color: blue;"&gt;ROWS&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum33" style="color: #606060;"&gt;  33:&lt;/span&gt;         &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; sys.indexes &lt;span style="color: blue;"&gt;AS&lt;/span&gt; I   &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum34" style="color: #606060;"&gt;  34:&lt;/span&gt;         &lt;span style="color: blue;"&gt;INNER&lt;/span&gt; &lt;span style="color: blue;"&gt;JOIN&lt;/span&gt; sys.tables T&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum35" style="color: #606060;"&gt;  35:&lt;/span&gt;         &lt;span style="color: blue;"&gt;ON&lt;/span&gt; T.OBJECT_ID = I.OBJECT_ID&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum36" style="color: #606060;"&gt;  36:&lt;/span&gt;         &lt;span style="color: blue;"&gt;INNER&lt;/span&gt; &lt;span style="color: blue;"&gt;join&lt;/span&gt; sys.partitions &lt;span style="color: blue;"&gt;AS&lt;/span&gt; P&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum37" style="color: #606060;"&gt;  37:&lt;/span&gt;             &lt;span style="color: blue;"&gt;ON&lt;/span&gt; I.OBJECT_ID = P.OBJECT_ID&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum38" style="color: #606060;"&gt;  38:&lt;/span&gt;             &lt;span style="color: blue;"&gt;AND&lt;/span&gt; I.INDEX_ID = P.INDEX_ID&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum39" style="color: #606060;"&gt;  39:&lt;/span&gt;         &lt;span style="color: blue;"&gt;INNER&lt;/span&gt; &lt;span style="color: blue;"&gt;JOIN&lt;/span&gt; sys.dm_db_partition_stats &lt;span style="color: blue;"&gt;AS&lt;/span&gt; PS&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum40" style="color: #606060;"&gt;  40:&lt;/span&gt;             &lt;span style="color: blue;"&gt;ON&lt;/span&gt; P.PARTITION_ID = PS.PARTITION_ID&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum41" style="color: #606060;"&gt;  41:&lt;/span&gt;         &lt;span style="color: blue;"&gt;GROUP&lt;/span&gt; &lt;span style="color: blue;"&gt;BY&lt;/span&gt; T.NAME, I.NAME, I.TYPE_DESC, I.INDEX_ID, P.PARTITION_NUMBER&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum42" style="color: #606060;"&gt;  42:&lt;/span&gt; ) &lt;span style="color: blue;"&gt;AS&lt;/span&gt; stats&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum43" style="color: #606060;"&gt;  43:&lt;/span&gt; &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; ISNULL(@TABLENAME, TABLE_NAME) = TABLE_NAME&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Modyfikując zmienną @TABLENAME uzyskane wyniki będą dotyczyły tylko jednej tabeli.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-4163990447246783425?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/UCjdeqp3EkI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/4163990447246783425/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=4163990447246783425" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/4163990447246783425?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/4163990447246783425?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/UCjdeqp3EkI/rozmiar-tabel-i-indeksow-w-bazie-danych.html" title="Rozmiar tabel i indeksów w bazie danych" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2012/02/rozmiar-tabel-i-indeksow-w-bazie-danych.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MGQXY5fyp7ImA9WhRUFEk.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-85514374910824663</id><published>2012-01-24T23:42:00.001+01:00</published><updated>2012-01-24T23:50:20.827+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-24T23:50:20.827+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dobre praktyki" /><category scheme="http://www.blogger.com/atom/ns#" term="DDL" /><category scheme="http://www.blogger.com/atom/ns#" term="DML" /><title>Sprawdzanie obiektów przed operacją modyfikacji schematu bazy danych</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/onxN5sJMYmgCBL35IQ0iAZGCL4c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/onxN5sJMYmgCBL35IQ0iAZGCL4c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/onxN5sJMYmgCBL35IQ0iAZGCL4c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/onxN5sJMYmgCBL35IQ0iAZGCL4c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;W &lt;a href="http://updatedev.blogspot.com/2012/01/sprawdzanie-danych-przed-operacjami.html"&gt;poprzednim poście&lt;/a&gt; pisałem na temat sprawdzania danych przed ich modyfikacją. Obiecałem także napisać kilka słów na temat pisania skryptów zmieniających schemat bazy danych, które będą mogły być wykonane wielokrotnie.&lt;br /&gt;
Poniższy skrypt stworzy przykładową strukturę bazy danych.&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;USE&lt;/span&gt; TEMPDB&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;GO&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;CREATE&lt;/span&gt; &lt;span style="color: blue;"&gt;TABLE&lt;/span&gt; COMPANY (&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     COMPANY_ID &lt;span style="color: blue;"&gt;INT&lt;/span&gt; &lt;span style="color: blue;"&gt;IDENTITY&lt;/span&gt; &lt;span style="color: blue;"&gt;NOT&lt;/span&gt; &lt;span style="color: blue;"&gt;NULL&lt;/span&gt; &lt;span style="color: blue;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color: blue;"&gt;KEY&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     NAME NVARCHAR(20) &lt;span style="color: blue;"&gt;NOT&lt;/span&gt; &lt;span style="color: blue;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;     DELETED &lt;span style="color: blue;"&gt;BIT&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt; &lt;span style="color: blue;"&gt;GO&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt; &lt;span style="color: blue;"&gt;CREATE&lt;/span&gt; &lt;span style="color: blue;"&gt;TABLE&lt;/span&gt; BRANCH (&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;     BRANCH_ID &lt;span style="color: blue;"&gt;INT&lt;/span&gt; &lt;span style="color: blue;"&gt;NOT&lt;/span&gt; &lt;span style="color: blue;"&gt;NULL&lt;/span&gt; &lt;span style="color: blue;"&gt;IDENTITY&lt;/span&gt; &lt;span style="color: blue;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color: blue;"&gt;KEY&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt;     COMPANY_ID &lt;span style="color: blue;"&gt;INT&lt;/span&gt; &lt;span style="color: blue;"&gt;NOT&lt;/span&gt; &lt;span style="color: blue;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt;     NAME NVARCHAR(20) &lt;span style="color: blue;"&gt;NOT&lt;/span&gt; &lt;span style="color: blue;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum15" style="color: #606060;"&gt;  15:&lt;/span&gt;     &lt;span style="color: blue;"&gt;CONSTRAINT&lt;/span&gt; FK_BRANCH_COMPANY &lt;span style="color: blue;"&gt;FOREIGN&lt;/span&gt; &lt;span style="color: blue;"&gt;KEY&lt;/span&gt;(COMPANY_ID) &lt;span style="color: blue;"&gt;REFERENCES&lt;/span&gt; COMPANY(COMPANY_ID)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum16" style="color: #606060;"&gt;  16:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum17" style="color: #606060;"&gt;  17:&lt;/span&gt; &lt;span style="color: blue;"&gt;GO&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum18" style="color: #606060;"&gt;  18:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum19" style="color: #606060;"&gt;  19:&lt;/span&gt; ;&lt;span style="color: blue;"&gt;WITH&lt;/span&gt; CTE &lt;span style="color: blue;"&gt;AS&lt;/span&gt; (&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum20" style="color: #606060;"&gt;  20:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'Company 1'&lt;/span&gt; &lt;span style="color: blue;"&gt;AS&lt;/span&gt; NAME, 0 &lt;span style="color: blue;"&gt;AS&lt;/span&gt; DELETED &lt;span style="color: blue;"&gt;UNION&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum21" style="color: #606060;"&gt;  21:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'Company 2'&lt;/span&gt;, 0 &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum22" style="color: #606060;"&gt;  22:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum23" style="color: #606060;"&gt;  23:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum24" style="color: #606060;"&gt;  24:&lt;/span&gt; INSERT &lt;span style="color: blue;"&gt;INTO&lt;/span&gt; COMPANY (NAME, DELETED)&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum25" style="color: #606060;"&gt;  25:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; NAME, DELETED &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; CTE &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum26" style="color: #606060;"&gt;  26:&lt;/span&gt; &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; &lt;span style="color: blue;"&gt;NOT&lt;/span&gt; &lt;span style="color: blue;"&gt;EXISTS&lt;/span&gt;(&lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; COMPANY &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; NAME = CTE.NAME)&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum27" style="color: #606060;"&gt;  27:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum28" style="color: #606060;"&gt;  28:&lt;/span&gt; ;&lt;span style="color: blue;"&gt;WITH&lt;/span&gt; CTE &lt;span style="color: blue;"&gt;AS&lt;/span&gt; (&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum29" style="color: #606060;"&gt;  29:&lt;/span&gt;     &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'Branch 1'&lt;/span&gt; &lt;span style="color: blue;"&gt;AS&lt;/span&gt; NAME, &lt;span style="color: #006080;"&gt;'Company 1'&lt;/span&gt; &lt;span style="color: blue;"&gt;AS&lt;/span&gt; COMPANY_NAME &lt;span style="color: blue;"&gt;UNION&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum30" style="color: #606060;"&gt;  30:&lt;/span&gt;     &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'Branch 2'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'Company 1'&lt;/span&gt; &lt;span style="color: blue;"&gt;UNION&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum31" style="color: #606060;"&gt;  31:&lt;/span&gt;     &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'Branch 1'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'Company 2'&lt;/span&gt; &lt;span style="color: blue;"&gt;UNION&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum32" style="color: #606060;"&gt;  32:&lt;/span&gt;     &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'Branch 2'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'Company 2'&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum33" style="color: #606060;"&gt;  33:&lt;/span&gt; ), CTE2 &lt;span style="color: blue;"&gt;AS&lt;/span&gt; (&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum34" style="color: #606060;"&gt;  34:&lt;/span&gt;     &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; CTE.NAME, COMPANY.COMPANY_ID &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; CTE&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum35" style="color: #606060;"&gt;  35:&lt;/span&gt;     &lt;span style="color: blue;"&gt;INNER&lt;/span&gt; &lt;span style="color: blue;"&gt;JOIN&lt;/span&gt; COMPANY&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum36" style="color: #606060;"&gt;  36:&lt;/span&gt;     &lt;span style="color: blue;"&gt;ON&lt;/span&gt; CTE.COMPANY_NAME = COMPANY.NAME&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum37" style="color: #606060;"&gt;  37:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum38" style="color: #606060;"&gt;  38:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum39" style="color: #606060;"&gt;  39:&lt;/span&gt; INSERT &lt;span style="color: blue;"&gt;INTO&lt;/span&gt; BRANCH (COMPANY_ID, NAME)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum40" style="color: #606060;"&gt;  40:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; COMPANY_ID, NAME &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; CTE2&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum41" style="color: #606060;"&gt;  41:&lt;/span&gt; &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; &lt;span style="color: blue;"&gt;NOT&lt;/span&gt; &lt;span style="color: blue;"&gt;EXISTS&lt;/span&gt;(&lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; BRANCH &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; NAME = CTE2.NAME &lt;span style="color: blue;"&gt;AND&lt;/span&gt; COMPANY_ID = CTE2.COMPANY_ID)&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Załóżmy, że wystąpiły zmiany w specyfikacji aplikacji, która korzysta z powyższych tabel i kolumna DELETED powinna zostać przeniesiona z tabeli COMPANY do tabeli BRANCH.&lt;br /&gt;
&lt;br /&gt;
Zadanie to zrealizuje prosty skrypt&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;ALTER&lt;/span&gt; &lt;span style="color: blue;"&gt;TABLE&lt;/span&gt; BRANCH &lt;span style="color: blue;"&gt;ADD&lt;/span&gt; DELETED BIT&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
W przypadku pierwszego wykonania wszystko zadziała poprawnie i kolumna zostanie dodane do tabeli BRANCH. Jak już wspomniałem w poprzednim poście przeważnie moja kontrola nad wykonywaniem skryptów kończy się w momencie dodania kodu do repozytorium. Z racji tego, że nie przepadam za odpowiadaniem na maile związane z błędami wykonania skryptów zawsze staram się zabezpieczyć przed sytuacją gdzie skrypt wykonany jest ponownie i błąd następującej treści mógłby wystąpić.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: red; font-family: Courier New;"&gt;Msg 2705, Level 16, State 4, Line 1&lt;br /&gt;    &lt;br /&gt;Column names in each table must be unique. Column name 'DELETED' in table 'BRANCH' is specified more than once.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;



Spawdzanie czy dana kolumna już istnieje w tabeli&lt;/h2&gt;
&lt;br /&gt;
Tak jak w przypadku operacji DML, opisanych w &lt;a href="http://updatedev.blogspot.com/2012/01/sprawdzanie-danych-przed-operacjami.html"&gt;poprzednim poście&lt;/a&gt;, tak i tym razem rozwiązanie wymaga dodania tylko jednego warunku.&lt;br /&gt;
&lt;br /&gt;
Poniższy skrypt może być wykonywany wielokrotnie, bez obaw, że pojawi się błąd jak powyżej.&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;IF&lt;/span&gt; &lt;span style="color: blue;"&gt;NOT&lt;/span&gt; &lt;span style="color: blue;"&gt;EXISTS&lt;/span&gt;(&lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; SYS.COLUMNS &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; NAME = &lt;span style="color: #006080;"&gt;'DELETED'&lt;/span&gt; &lt;span style="color: blue;"&gt;AND&lt;/span&gt; OBJECT_ID = OBJECT_ID(&lt;span style="color: #006080;"&gt;'BRANCH'&lt;/span&gt;))&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;ALTER&lt;/span&gt; &lt;span style="color: blue;"&gt;TABLE&lt;/span&gt; BRANCH &lt;span style="color: blue;"&gt;ADD&lt;/span&gt; DELETED BIT&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Zapytanie podobnego typu może być wykonane także dla innych typów obiektów. Indeksy, tabele, widoki, wszystkie te elementy istnieją w widokach systemowych. Mogą zostać one odpytane przed dodaniem nowego obiektu.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;



Sprawdzanie czy kolumna istnieje przed aktualizacją danych&lt;/h2&gt;
&lt;br /&gt;
Załóżmy, że nowe wymagania dotyczące projektu mówią także, że wartość DELETED z tabeli COMPANY musi być zapisane kolumnie DELETED w tabeli BRANCH, oraz że kolumna DELETED musi być usunięta z tabeli COMPANY po całej aktualizacji.&lt;br /&gt;
&lt;br /&gt;
Skrypt ten mógłby przyjąć następującą postać&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;UPDATE&lt;/span&gt; BRANCH &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;SET&lt;/span&gt; DELETED = COMPANY.DELETED&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; COMPANY&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;INNER&lt;/span&gt; &lt;span style="color: blue;"&gt;JOIN&lt;/span&gt; BRANCH&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt; &lt;span style="color: blue;"&gt;ON&lt;/span&gt; BRANCH.COMPANY_ID = COMPANY.COMPANY_ID&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt; &lt;span style="color: blue;"&gt;IF&lt;/span&gt; &lt;span style="color: blue;"&gt;EXISTS&lt;/span&gt;(&lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; SYS.COLUMNS &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; NAME = &lt;span style="color: #006080;"&gt;'DELETED'&lt;/span&gt; &lt;span style="color: blue;"&gt;AND&lt;/span&gt; OBJECT_ID = OBJECT_ID(&lt;span style="color: #006080;"&gt;'COMPANY'&lt;/span&gt;))&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt; &lt;span style="color: blue;"&gt;ALTER&lt;/span&gt; &lt;span style="color: blue;"&gt;TABLE&lt;/span&gt; COMPANY&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt; &lt;span style="color: blue;"&gt;DROP&lt;/span&gt; &lt;span style="color: blue;"&gt;COLUMN&lt;/span&gt; DELETED&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt; GO&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Wszystko będzie działać pod warunkiem, że skrypt nie zostanie wykonany ponownie. Wtedy przy próbie kompilacji wysypie się on bo kolumna DELETED już nie istnieje w tabeli COMPANY.&lt;br /&gt;
&lt;br /&gt;
Problemu tego typu nie da się uniknąć poprzez dodanie tylko i wyłącznie następującego warunku przed aktualizacją danych&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;IF&lt;/span&gt; &lt;span style="color: blue;"&gt;EXISTS&lt;/span&gt;(&lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; SYS.COLUMNS &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; NAME = &lt;span style="color: #006080;"&gt;'DELETED'&lt;/span&gt; &lt;span style="color: blue;"&gt;AND&lt;/span&gt; OBJECT_ID = OBJECT_ID(&lt;span style="color: #006080;"&gt;'COMPANY'&lt;/span&gt;))&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Aby obejść ten problem i mieć święty spokój w momencie kiedy skrypt ponownie byłby uruchomiony trzeba skorzystać z dynamicznego SQL-a.&lt;br /&gt;
&lt;br /&gt;
Zapytanie, które będzie aktualizować dane przyjmie wtedy następującą postać&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;IF&lt;/span&gt; &lt;span style="color: blue;"&gt;EXISTS&lt;/span&gt;(&lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; SYS.COLUMNS &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; NAME = &lt;span style="color: #006080;"&gt;'DELETED'&lt;/span&gt; &lt;span style="color: blue;"&gt;AND&lt;/span&gt; OBJECT_ID = OBJECT_ID(&lt;span style="color: #006080;"&gt;'COMPANY'&lt;/span&gt;))&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;BEGIN&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;     &lt;span style="color: blue;"&gt;DECLARE&lt;/span&gt; @&lt;span style="color: blue;"&gt;SQL&lt;/span&gt; NVARCHAR(&lt;span style="color: blue;"&gt;MAX&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     &lt;span style="color: blue;"&gt;SET&lt;/span&gt; @&lt;span style="color: blue;"&gt;SQL&lt;/span&gt; = &lt;span style="color: #006080;"&gt;'UPDATE BRANCH &lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     SET DELETED = COMPANY.DELETED&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     FROM COMPANY&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;     INNER JOIN BRANCH&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;     ON BRANCH.COMPANY_ID = COMPANY.COMPANY_ID'&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;     &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;     &lt;span style="color: blue;"&gt;EXEC&lt;/span&gt;(@&lt;span style="color: blue;"&gt;SQL&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt; END&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Warto więc dodać kilka lini kodu więcej, aby mieć pewność, że w momencie wielokrotnego wykonania skryptu nie zostaną zgłoszone jakiekolwiek błędy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-85514374910824663?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/z2ZEqOMviEw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/85514374910824663/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=85514374910824663" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/85514374910824663?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/85514374910824663?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/z2ZEqOMviEw/sprawdzanie-obiektow-przed-operacja.html" title="Sprawdzanie obiektów przed operacją modyfikacji schematu bazy danych" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2012/01/sprawdzanie-obiektow-przed-operacja.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEAHRXo8cSp7ImA9WhRUFEk.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-6236667923878806600</id><published>2012-01-24T00:23:00.001+01:00</published><updated>2012-01-24T23:05:34.479+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-24T23:05:34.479+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dobre praktyki" /><category scheme="http://www.blogger.com/atom/ns#" term="DML" /><title>Sprawdzanie danych przed operacjami modyfikacji</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/lZ9lidrggNVAWhKxtxLynxIk4cs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lZ9lidrggNVAWhKxtxLynxIk4cs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/lZ9lidrggNVAWhKxtxLynxIk4cs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lZ9lidrggNVAWhKxtxLynxIk4cs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Jednym z najprostrzych sposobów na uniknięcie błedów, które mogą pojawić się podczas wykonywanie skryptów jest weryfikacja danych, które ewentualnie powinny być zmodyfikowane.&lt;br /&gt;
W momencie kiedy pisze jakiś skrypt moja kontrola nad nim kończy się w momencie kiedy zostanie dodany on to repozytorium kodu.&lt;br /&gt;
Później nie mam już żadnego wpływu na to kto będzie go uruchamiał i jak wiele razy. Tak więc aby zabezpieczyć się przed ewentualnymi błędami, które mogą wyniknąć z wielokrotnego wykonania skryptów zawsze staram się działać w tej kwesti proaktywanie.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;



Dodawanie danych tylko jeżeli ich nie ma&lt;/h2&gt;
W przypadku, gdy nowe dane powinny zostać dodane do tabeli najłatwiejszym sposobem unikcięcia błędów jest sprawdzenie czy danych tych przypadkiem w tabeli już nie ma.&lt;br /&gt;
Weźmy dla przykładu tabelę z kodami pocztowymi&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;create&lt;/span&gt; &lt;span style="color: blue;"&gt;table&lt;/span&gt; Postcodes (&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt;     postcode &lt;span style="color: blue;"&gt;char&lt;/span&gt;(6) &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: blue;"&gt;null&lt;/span&gt; &lt;span style="color: blue;"&gt;primary&lt;/span&gt; &lt;span style="color: blue;"&gt;key&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;     city nvarchar(30)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; )&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Załóżmy teraz, że musimy dodać następujące dane do tabeli&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom-color: silver; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: silver; border-left-style: solid; border-left-width: 1px; border-right-color: silver; border-right-style: solid; border-right-width: 1px; border-top-color: silver; border-top-style: solid; border-top-width: 1px; cursor: text; direction: ltr; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 20px; max-height: 200px; overflow-x: auto; overflow-y: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div style="text-align: -webkit-auto;"&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',courier,monospace; font-size: 11px; line-height: 16px; white-space: pre;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',courier,monospace; font-size: 11px; line-height: 16px; white-space: pre;"&gt; insert &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',courier,monospace; font-size: 11px; line-height: 16px; white-space: pre;"&gt;&lt;span style="color: blue;"&gt;into&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',courier,monospace; font-size: 11px; line-height: 16px; white-space: pre;"&gt; Postcodes (postcode, city)&lt;/span&gt;&lt;/div&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;select&lt;/span&gt; &lt;span style="color: #006080;"&gt;'30-001'&lt;/span&gt;, N&lt;span style="color: #006080;"&gt;'Kraków'&lt;/span&gt; &lt;span style="color: blue;"&gt;union&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;select&lt;/span&gt; &lt;span style="color: #006080;"&gt;'30-123'&lt;/span&gt;, N&lt;span style="color: #006080;"&gt;'Kraków'&lt;/span&gt; &lt;span style="color: blue;"&gt;union&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;select&lt;/span&gt; &lt;span style="color: #006080;"&gt;'00-001'&lt;/span&gt;, N&lt;span style="color: #006080;"&gt;'Warszawa'&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Pierwzze wykonanie skryptu oczywiście się powiedzie, ale jak już wspomniałem wcześniej bardzo często kontrola nad tym kto wykonuje i ile razy skrypt jest niemożliwa.&lt;br /&gt;
&lt;br /&gt;
Wykonując powyższy skryp dodawania danych ponownie pojawi się błąd następującej treści.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: 'Courier New';"&gt;&lt;span style="color: red;"&gt;Msg 2627, Level 14, State 1, Line 1&lt;br /&gt;      &lt;br /&gt;Violation of PRIMARY KEY constraint 'PK__Postcode__F27E9E8B0DAF0CB0'. Cannot insert duplicate key in object 'dbo.Postcodes'.&lt;br /&gt;&lt;br /&gt;      &lt;/span&gt;The statement has been terminated.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Niespodzianek tego typu łatwo jest uniknąć pod warunkiem, że dane które mają być dodane na wstępie zostaną zweryfikowane pod kątem ich istnienia w tabeli.&lt;br /&gt;
&lt;br /&gt;
Modyfikując zapytanie w następujący sposób problem tego ile razy skrypt zostanie uruchomiony przestaje istnieć.&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom-color: silver; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: silver; border-left-style: solid; border-left-width: 1px; border-right-color: silver; border-right-style: solid; border-right-width: 1px; border-top-color: silver; border-top-style: solid; border-top-width: 1px; cursor: text; direction: ltr; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 20px; max-height: 200px; overflow-x: auto; overflow-y: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; ;&lt;span style="color: blue;"&gt;with&lt;/span&gt; cte &lt;span style="color: blue;"&gt;as&lt;/span&gt; (&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;select&lt;/span&gt; &lt;span style="color: #006080;"&gt;'30-001'&lt;/span&gt; postcode, N&lt;span style="color: #006080;"&gt;'Kraków'&lt;/span&gt; city &lt;span style="color: blue;"&gt;union&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;select&lt;/span&gt; &lt;span style="color: #006080;"&gt;'30-123'&lt;/span&gt;, N&lt;span style="color: #006080;"&gt;'Kraków'&lt;/span&gt; &lt;span style="color: blue;"&gt;union&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;select&lt;/span&gt; &lt;span style="color: #006080;"&gt;'00-001'&lt;/span&gt;, N&lt;span style="color: #006080;"&gt;'Warszawa'&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt; insert &lt;span style="color: blue;"&gt;into&lt;/span&gt; Postcodes (postcode, city)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt; &lt;span style="color: blue;"&gt;select&lt;/span&gt; postcode, city &lt;span style="color: blue;"&gt;from&lt;/span&gt; cte &lt;span style="color: blue;"&gt;where&lt;/span&gt; &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: blue;"&gt;exists&lt;/span&gt; (&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;     &lt;span style="color: blue;"&gt;select&lt;/span&gt; * &lt;span style="color: blue;"&gt;from&lt;/span&gt; postcodes &lt;span style="color: blue;"&gt;where&lt;/span&gt; postcode = cte.postcode&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt; )&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
W przypadku SQL Servera 2008 i wyższych zapytanie można by zmodyfikować i użyć MERGE&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom-color: silver; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: silver; border-left-style: solid; border-left-width: 1px; border-right-color: silver; border-right-style: solid; border-right-width: 1px; border-top-color: silver; border-top-style: solid; border-top-width: 1px; cursor: text; direction: ltr; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 20px; max-height: 200px; overflow-x: auto; overflow-y: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; ;&lt;span style="color: blue;"&gt;with&lt;/span&gt; cte &lt;span style="color: blue;"&gt;as&lt;/span&gt; (&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;select&lt;/span&gt; &lt;span style="color: #006080;"&gt;'30-001'&lt;/span&gt; postcode, N&lt;span style="color: #006080;"&gt;'Kraków'&lt;/span&gt; city &lt;span style="color: blue;"&gt;union&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;select&lt;/span&gt; &lt;span style="color: #006080;"&gt;'30-123'&lt;/span&gt;, N&lt;span style="color: #006080;"&gt;'Kraków'&lt;/span&gt; &lt;span style="color: blue;"&gt;union&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;select&lt;/span&gt; &lt;span style="color: #006080;"&gt;'00-001'&lt;/span&gt;, N&lt;span style="color: #006080;"&gt;'Warszawa'&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt; merge Postcodes p&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt; &lt;span style="color: blue;"&gt;using&lt;/span&gt; cte c&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt; &lt;span style="color: blue;"&gt;on&lt;/span&gt; p.postcode = c.postcode&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt; &lt;span style="color: blue;"&gt;when&lt;/span&gt; &lt;span style="color: blue;"&gt;not&lt;/span&gt; matched &lt;span style="color: blue;"&gt;then&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt; insert (postcode, city)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt; &lt;span style="color: blue;"&gt;values&lt;/span&gt; (postcode, city);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;


&lt;/h2&gt;
&lt;h2&gt;



Weryfikacja danych przed aktualizacją&lt;/h2&gt;
Podobny problem może zaistnieć w przypadku aktualizacji danych&lt;br /&gt;
&lt;br /&gt;
Załóżmy, że omyłkowo do tabeli został dodany kod pocztowy 00-000 zamiast 00-001&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: blue;"&gt;exists&lt;/span&gt;(&lt;span style="color: blue;"&gt;select&lt;/span&gt; * &lt;span style="color: blue;"&gt;from&lt;/span&gt; Postcodes &lt;span style="color: blue;"&gt;where&lt;/span&gt; postcode = &lt;span style="color: #006080;"&gt;'00-000'&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; insert &lt;span style="color: blue;"&gt;into&lt;/span&gt; Postcodes (postcode, city)&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;values&lt;/span&gt;(&lt;span style="color: #006080;"&gt;'00-000'&lt;/span&gt;, N&lt;span style="color: #006080;"&gt;'Warszawa'&lt;/span&gt;)&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Wykonując aktualizację bez sprawdzenie czy poprawny kod pocztowy już istnieje narażamy sie ponownie na błąd&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;update&lt;/span&gt; Postcodes&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;set&lt;/span&gt; postcode = &lt;span style="color: #006080;"&gt;'00-001'&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;where&lt;/span&gt; postcode = &lt;span style="color: #006080;"&gt;'00-000'&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-family: 'Courier New';"&gt;&lt;span style="color: red;"&gt;Msg 2627, Level 14, State 1, Line 1&lt;br /&gt;      &lt;br /&gt;Violation of PRIMARY KEY constraint 'PK__Postcode__F27E9E8B0DAF0CB0'. Cannot insert duplicate key in object 'dbo.Postcodes'.&lt;br /&gt;&lt;br /&gt;      &lt;/span&gt;The statement has been terminated.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Zabezpieczenie się przed tego typu problemem wymaga tylko jednej dodatkowej lini kodu&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom-color: silver; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: silver; border-left-style: solid; border-left-width: 1px; border-right-color: silver; border-right-style: solid; border-right-width: 1px; border-top-color: silver; border-top-style: solid; border-top-width: 1px; cursor: text; direction: ltr; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 20px; max-height: 200px; overflow-x: auto; overflow-y: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: blue;"&gt;exists&lt;/span&gt;(&lt;span style="color: blue;"&gt;select&lt;/span&gt; * &lt;span style="color: blue;"&gt;from&lt;/span&gt; Postcodes &lt;span style="color: blue;"&gt;where&lt;/span&gt; postcode = &lt;span style="color: #006080;"&gt;'00-001'&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;update&lt;/span&gt; Postcodes&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;set&lt;/span&gt; postcode = &lt;span style="color: #006080;"&gt;'00-001'&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;where&lt;/span&gt; postcode = &lt;span style="color: #006080;"&gt;'00-000'&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Jak widac na powyższych przykładach zabezpieczenie się przed błędami, które mogą wyniknąć z wielokrotnego uruchamiania skryptów wymaga niewielkiej ilości dodatkowego kodu.&lt;br /&gt;
&lt;br /&gt;
W kolejnym poście napiszę o operacjach modyfikacji struktury bazy danych i jak się zabezpieczyć przed wpadkami związanymi wielokrotnym wykonywaniem skryptów.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-6236667923878806600?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/ekckKh-KVuU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/6236667923878806600/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=6236667923878806600" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/6236667923878806600?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/6236667923878806600?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/ekckKh-KVuU/sprawdzanie-danych-przed-operacjami.html" title="Sprawdzanie danych przed operacjami modyfikacji" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2012/01/sprawdzanie-danych-przed-operacjami.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4GR3o9fCp7ImA9WhRVGU8.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-6231218284438033265</id><published>2012-01-18T23:45:00.001+01:00</published><updated>2012-01-19T00:05:26.464+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-19T00:05:26.464+01:00</app:edited><title>Usuń tabelę z tabel systemowych</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Eo3JKq0CNP_zPhkzmM5FsNba0ts/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Eo3JKq0CNP_zPhkzmM5FsNba0ts/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Eo3JKq0CNP_zPhkzmM5FsNba0ts/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Eo3JKq0CNP_zPhkzmM5FsNba0ts/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Chciałem dalej kontynuować poprzedni wątek dotyczący blokowania zasobów. Wszystko jednak diabli wzięli. Otóż musiałem interweniować dzisiaj po tym jak do systemu wdarła się poprawka powodująca, że główna funkcjonalność systemu przestała działać. Tak więc dzisiaj będzie o tym jak nie usuwać danych z bazy.&lt;br /&gt;
Załóżmy, że mamy następujace dane&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;CREATE&lt;/span&gt; &lt;span style="color: blue;"&gt;TABLE&lt;/span&gt; SYSTEM_TABLES (&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt;     TABLE_NAME &lt;span style="color: blue;"&gt;VARCHAR&lt;/span&gt;(126)&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt; &lt;span style="color: blue;"&gt;CREATE&lt;/span&gt; &lt;span style="color: blue;"&gt;TABLE&lt;/span&gt; SYSTEM_SETTINGS (&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     NAME &lt;span style="color: blue;"&gt;VARCHAR&lt;/span&gt;(100),&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;     &lt;span style="color: blue;"&gt;VALUE&lt;/span&gt; NVARCHAR(20)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt; &lt;span style="color: blue;"&gt;CREATE&lt;/span&gt; &lt;span style="color: blue;"&gt;TABLE&lt;/span&gt; INTEREST_RATES (&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;     NAME &lt;span style="color: blue;"&gt;VARCHAR&lt;/span&gt;(20),&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;     &lt;span style="color: blue;"&gt;VALUE&lt;/span&gt; &lt;span style="color: blue;"&gt;DECIMAL&lt;/span&gt;(4,2)&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum15" style="color: #606060;"&gt;  15:&lt;/span&gt; INSERT &lt;span style="color: blue;"&gt;INTO&lt;/span&gt; SYSTEM_TABLES &lt;span style="color: blue;"&gt;VALUES&lt;/span&gt;(&lt;span style="color: #006080;"&gt;'SYSTEM_SETTINGS'&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum16" style="color: #606060;"&gt;  16:&lt;/span&gt; INSERT &lt;span style="color: blue;"&gt;INTO&lt;/span&gt; SYSTEM_TABLES &lt;span style="color: blue;"&gt;VALUES&lt;/span&gt;(&lt;span style="color: #006080;"&gt;'INTEREST_RATES'&lt;/span&gt;)&lt;/pre&gt;
&lt;br /&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum17" style="color: #606060;"&gt;  17:&lt;/span&gt; INSERT &lt;span style="color: blue;"&gt;INTO&lt;/span&gt; SYSTEM_SETTINGS&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum18" style="color: #606060;"&gt;  18:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'Language'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'English'&lt;/span&gt; &lt;span style="color: blue;"&gt;UNION&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum19" style="color: #606060;"&gt;  19:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'AnonymousUsers'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'0'&lt;/span&gt; &lt;span style="color: blue;"&gt;UNION&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum20" style="color: #606060;"&gt;  20:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'StrongPassword'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'1'&lt;/span&gt; &lt;span style="color: blue;"&gt;UNION&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum21" style="color: #606060;"&gt;  21:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'PasswordHistory'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'3'&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum22" style="color: #606060;"&gt;  22:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum23" style="color: #606060;"&gt;  23:&lt;/span&gt; INSERT &lt;span style="color: blue;"&gt;INTO&lt;/span&gt; INTEREST_RATES&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum24" style="color: #606060;"&gt;  24:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'Reference'&lt;/span&gt;, 4.5 &lt;span style="color: blue;"&gt;UNION&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum25" style="color: #606060;"&gt;  25:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'Lombard'&lt;/span&gt;, 6.0 &lt;span style="color: blue;"&gt;UNION&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum26" style="color: #606060;"&gt;  26:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'Deposit'&lt;/span&gt;, 3.0 &lt;span style="color: blue;"&gt;UNION&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum27" style="color: #606060;"&gt;  27:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #006080;"&gt;'Rediscount'&lt;/span&gt;, 4.75&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Tabela SYSTEM_TABLES przechowuje nazwy tabel istotnych dla funkcjonowania systemu. Z różnych powodów jedną z tych tabel (INTEREST_RATES) trzeba było usunąć z SYSTEM_TABLES.&lt;br /&gt;
&lt;br /&gt;
Banalne z pozoru zapytanie, a wykonane niepoprawnie spowodowało, że system przestał działać.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;

DELETE z iloczynem kartezjańskim&lt;/h2&gt;
Mały quiz teraz. Jaki będzie rezultat poniższego zapytania&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;DELETE&lt;/span&gt; INTEREST_RATES &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; SYSTEM_TABLES&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Możliwe odpowiedzi:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Błąd składni&lt;/li&gt;
&lt;li&gt;Zapytanie się wykona ale nic nie zostanie usunięte&lt;/li&gt;
&lt;li&gt;Rekord INTEREST_RATES zostanie usunięy z SYSTEM_TABLES&lt;/li&gt;
&lt;li&gt;Cała zawartość tabeli INTEREST_RATES zostanie usunięta&lt;/li&gt;
&lt;/ol&gt;
Zachęcam do komentowania, bez uprzedniego testowania zapytania&lt;br /&gt;
&lt;br /&gt;
No, dobra odpowiem sam na to pytanie. Otóż poprawna odpowiedź to ta oznaczona nr 4.&lt;br /&gt;
&lt;br /&gt;
Składnia zapytania jest jak najbardziej poprawna. Jeżeli byłoby to zapytanie SELECT to jego postać byłaby następująca.&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color: blue;"&gt;FROM&lt;/span&gt; INTEREST_RATES, SYSTEM_TABLES&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Jest to nic innego jak iloczyn kartezjański.&lt;br /&gt;
&lt;br /&gt;
Z tym, że założenie było takie aby usunąć tylko jeden rekord z SYSTEM_TABLES w następujący sposób&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;DELETE&lt;/span&gt; SYSTEM_TABLES &lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; TABLE_NAME = &lt;span style="color: #006080;"&gt;'INTEREST_RATES'&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Tutaj aż się prosi aby dołączyć referencje do mojego &lt;a href="http://www.updatedev.blogspot.com/2012/01/t-sql-od-podstaw-cz-1.html"&gt;pierwszego postu&lt;/a&gt; dotyczącego podstaw SQL. Prawdę mówiąc nie myślałem, że tak szybko będę musiał powracać to tego tematu.&lt;br /&gt;
&lt;br /&gt;
I na koniec jeszcze jedna ciekawostka. W języku angielskim polecenie mogłoby przybrać następującą postać:&lt;br /&gt;
&lt;br /&gt;
You must &lt;span style="background-color: white; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DELETE INTEREST_RATES FROM SYSTEM_TABLES&lt;/span&gt; to make this feature working&lt;br /&gt;
&lt;br /&gt;
Język programowania i naturalny maja dużo ze sobą wspólnego. Tylko, że czasami rezultat może być inny od oczekiwanego.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-6231218284438033265?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/8MB3wjb2ecM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/6231218284438033265/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=6231218284438033265" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/6231218284438033265?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/6231218284438033265?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/8MB3wjb2ecM/usun-tabele-z-tabel-systemowych.html" title="Usuń tabelę z tabel systemowych" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2012/01/usun-tabele-z-tabel-systemowych.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cCRXw9eip7ImA9WhRVGEk.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-2750031381025686716</id><published>2012-01-17T02:00:00.001+01:00</published><updated>2012-01-17T23:57:44.262+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-17T23:57:44.262+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Transakcje" /><category scheme="http://www.blogger.com/atom/ns#" term="optymalizacja" /><title>T-SQL od podstaw cz. 2</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZpCgng3W8Qn4Scot131YWpoicm0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZpCgng3W8Qn4Scot131YWpoicm0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZpCgng3W8Qn4Scot131YWpoicm0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZpCgng3W8Qn4Scot131YWpoicm0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;W &lt;a href="http://www.updatedev.blogspot.com/2012/01/t-sql-od-podstaw-cz-1.html" title="transakcje w SQL Server"&gt;poprzednim wpisie&lt;/a&gt; poruszyłem temat transakcji i jak sie zabezpieczyć przed sytuacją taką, że wiecej danych zostanie zaktualizowanych niż oczekiwano.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;

Blokowanie zasobów&lt;/h2&gt;
Pozostawienie otwartej transakcji nawet na chwile ma negatywny wpływ na inne operacje na bazie danych.&lt;br /&gt;
W momencie kiedy transakcja jest otwarta i tabela jest aktualizowana inne zapytanie domyślnie nie mogą odczytać danych dopóki transakcja aktualizująca dane nie zostanie zakończona. Ma to zapobiedz sytuacji takiej, że odczytywane danych w innych transakcjach mogą uledz zmianie w przypadku gdy aktualizacja się nie powiedzie z jakiegoś powodu.&lt;br /&gt;
Są przypadki, w których nie zależy nam na aptekarskim podejściu do zwróconych danych i pewien stopień błędu jest akceptowalny. Dodatkowo samo odczytywanie danych także ma wpływ na operacje aktualizujące te same dane w innej sesji.&lt;br /&gt;
W przypadku analizy danych na środowisku produkcyjnym w zdecydowanej większości przypadków zależy nam na tym by uniknąć sytuacji, w której to co robimy ma negatywny wpływ na pracę systemu.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;

Hint NOLOCK.&lt;/h2&gt;
Wykonując polecenie &lt;span style="font-family: Courier New;"&gt;SELECT&lt;/span&gt; z hintem &lt;span style="font-family: Courier New;"&gt;NOLOCK&lt;/span&gt; nie blokujemy zasobów ale także potęcjalnie możemy mieć taką sytuację, że odczytywane dane niekoniecznie będą takie same przy ponownym uruchomieniu zapytania.&lt;br /&gt;
Załóżmy, że mamy tabelę MyTable, z której chcemy pobrać wszystkie rekordy z wartością 1 w kolumnie val&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;create&lt;/span&gt; &lt;span style="color: blue;"&gt;table&lt;/span&gt; MyTable (&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt;     id uniqueidentifier &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: blue;"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;     val &lt;span style="color: blue;"&gt;char&lt;/span&gt;(1) &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: blue;"&gt;null&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt; &lt;span style="color: blue;"&gt;declare&lt;/span&gt; @i &lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt; &lt;span style="color: blue;"&gt;set&lt;/span&gt; @i = 0&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt; &lt;span style="color: blue;"&gt;while&lt;/span&gt; @i&amp;lt;=100&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt; &lt;span style="color: blue;"&gt;begin&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;     insert &lt;span style="color: blue;"&gt;into&lt;/span&gt; MyTable &lt;span style="color: blue;"&gt;values&lt;/span&gt;(newid(), @i%9)&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;     &lt;span style="color: blue;"&gt;set&lt;/span&gt; @i = @i + 1&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt; end&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Rezultat ten możemy uzyskać uruchamiając poniższe zapytanie&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;select&lt;/span&gt; * &lt;span style="color: blue;"&gt;from&lt;/span&gt; MyTable &lt;span style="color: blue;"&gt;where&lt;/span&gt; val = 2&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Jednakże w sytuacji, kiedy w innym procesie dane w tej samej tabeli są aktualizowane na odpowiedź może nam przyjść trochę poczekać.&lt;br /&gt;
&lt;br /&gt;
Załóżmy następującą sytuację. W transakcji nr 1 wykonujemy następujące zapytanie aktualizujące wartości w kolumnie val z 1 na 3&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;begin&lt;/span&gt; &lt;span style="color: blue;"&gt;tran&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;update&lt;/span&gt; MyTable&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;set&lt;/span&gt; val = 3&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;where&lt;/span&gt; val = 1&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Teraz wykonując ponownie zapytanie, w transakcji nr 2, pobierające rekordy z wartością 2 w kolumnie val będzie czekać aż pierwsza transakcja się zakończy. Może to trochę potrwać, szczególnie w sytuacji gdy ktoś rozpoczął transakcje a zapomniał ją zakończyć. Taka sytuacja już mi się kilka razy zdarzyła pracując na bazie danych dzielonej z innymi deweloperami.&lt;br /&gt;
&lt;br /&gt;
Z racji tego, że potrzebuje rezultat natychmiast i akceptowanla jest dla mnie sytuacja taka, że jakieś dane mogą zostać zmienione w międzyczasie w innej transakcji, zapytanie SELECT wykonuję z hintem NOLOCK.&lt;br /&gt;
&lt;br /&gt;
Zapytanie uruchamiam w transakcji nr 3.&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;select&lt;/span&gt; * &lt;span style="color: blue;"&gt;from&lt;/span&gt; MyTable &lt;span style="color: blue;"&gt;WITH&lt;/span&gt; (NOLOCK) &lt;span style="color: blue;"&gt;where&lt;/span&gt; val = 2&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Wynik w tym przypadku otrzymuję natychmiast, podczas, gdy drugie zapytanie ciągle czeka aż zasoby zostaną zwolnione.&lt;br /&gt;
&lt;br /&gt;
Teraz wracając do pierwszej transakcji zatwierdzam zapytanie&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;commit&lt;/span&gt; tran&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
W tym samym momencie w transakcji nr 2 dostaję wynik, taki sam jak w transakcji nr 3.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-2750031381025686716?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/ieOKgnugMzM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/2750031381025686716/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=2750031381025686716" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/2750031381025686716?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/2750031381025686716?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/ieOKgnugMzM/t-sql-od-podstaw-cz-2.html" title="T-SQL od podstaw cz. 2" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2012/01/t-sql-od-podstaw-cz-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8GR3g4eCp7ImA9WhRUE0g.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-4345920118721360571</id><published>2012-01-15T22:43:00.001+01:00</published><updated>2012-01-23T23:30:26.630+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-23T23:30:26.630+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Transakcje" /><category scheme="http://www.blogger.com/atom/ns#" term="dobre praktyki" /><category scheme="http://www.blogger.com/atom/ns#" term="T-SQL" /><title>T-SQL od podstaw cz. 1</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kT02-Bmh62tdbDCtlNRi8r1u34I/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kT02-Bmh62tdbDCtlNRi8r1u34I/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kT02-Bmh62tdbDCtlNRi8r1u34I/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kT02-Bmh62tdbDCtlNRi8r1u34I/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Postanowiłem sobie, że w tym roku będę blogował znacznie częściej niż miało to miejsce dotychczas. Jako, że w ostatnim czasie dość sporo czasu spędzam pomagając innym z SQL-em to postanowiłem, że będę pisał trochę praktycznych porad.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;


Transakcje w T-SQL&lt;/h2&gt;
Czy zdarzyło się wam kiedyś odpalić jakieś zapytanie aktualizujące tabelę, które przez przypadek zaktualizowało więcej rekordów niż tego oczekiwaliście?&lt;br /&gt;
&lt;br /&gt;
Nie jest to częsty problem ale pewnie każdemu się to kiedyś zdarzyło. W ostatnim czasie miałem przyjemność przywracania fragmentu bazy danych, która została zmieniona przez &lt;span style="font-family: 'courier new';"&gt;UPDATE&lt;/span&gt; bez klauzuli &lt;span style="font-family: 'courier new';"&gt;WHERE&lt;/span&gt;. Jednym słowem cała tabela została zaktualizowana i trzeba było ją odtworzyć z innego źródła. W moim przypadku, skopiowałem dane z innej bazy, która zawierała tą samą tabelę.&lt;br /&gt;
&lt;br /&gt;
Problemu by nie było gdyby   &lt;br /&gt;
· Zapytanie miało poprawną klauzulę &lt;span style="font-family: 'courier new';"&gt;WHERE&lt;/span&gt;    &lt;br /&gt;
· Byłoby uruchomione wewnątrz transakcji.    &lt;br /&gt;
&lt;br /&gt;
Zawsze zalecam zagnieżdżanie zapytań aktualizujących dane wewnątrz transakcji. Zapytanie jest wtedy wykonywane w trzech krokach.   &lt;br /&gt;
1. Otwarcie transakcji i zapytanie DML.    &lt;br /&gt;
2. Sprawdzenie rezultatu    &lt;br /&gt;
3. Zatwierdzenie lub cofnięcie transakcji w przypadku gdy liczba wierszy zaktualizowanych nie odpowiada oczekiwaniom.    &lt;br /&gt;
&lt;br /&gt;
W praktyce wygląda to następująco&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;begin&lt;/span&gt; &lt;span style="color: blue;"&gt;tran&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;update&lt;/span&gt; aspnet_Roles&lt;/pre&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;set&lt;/span&gt; Description = &lt;span style="color: #006080;"&gt;'System administrators'&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;where&lt;/span&gt; RoleName = &lt;span style="color: #006080;"&gt;'Admins'&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Po wykonaniu powyższego w oknie Messages sprawdzam ilość wierszy, które zostały zaktualizowane i jeżeli jest to 1, czyli tyle ile oczekuję to zatwierdzam transakcję poleceniem&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;commit&lt;/span&gt; tran&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
W przypadku gdyby rezultat byłby inny to cofam transakcję poleceniem&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"&gt;
&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;
&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;rollback&lt;/span&gt; tran&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Zweryfikować rezultat można także poprzez wykonanie zapytanie &lt;span style="font-family: 'courier new';"&gt;SELECT&lt;/span&gt; w tym samej sesji, bądź &lt;span style="font-family: 'courier new';"&gt;SELECT&lt;/span&gt; z hintem &lt;span style="font-family: 'courier new';"&gt;NOLOCK&lt;/span&gt; w dowolnej innej sesji.&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-4345920118721360571?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/mJ6ieW9hWVc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/4345920118721360571/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=4345920118721360571" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/4345920118721360571?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/4345920118721360571?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/mJ6ieW9hWVc/t-sql-od-podstaw-cz-1.html" title="T-SQL od podstaw cz. 1" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2012/01/t-sql-od-podstaw-cz-1.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8BQH89fip7ImA9WhdVEU8.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-4795917022943001135</id><published>2011-09-15T23:45:00.028+02:00</published><updated>2011-09-16T01:20:51.166+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-16T01:20:51.166+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Integralność danych" /><title>Intregralność danych i wartości NULL</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MAFIAEoQxKhrMv7Rb0-FBZJcpZc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MAFIAEoQxKhrMv7Rb0-FBZJcpZc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MAFIAEoQxKhrMv7Rb0-FBZJcpZc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MAFIAEoQxKhrMv7Rb0-FBZJcpZc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;font size="2"&gt;&lt;span style="font-family: trebuchet ms; font-size: 85%"&gt;&lt;font size="2"&gt;Pracowałem nad projektem, gdzie musiałem zapewnić integralność danych w tabeli, której kolumny mogą przyjmować wartość NULL. Do tego wartości w jednej kolumnie były zależne od danch w innej kolumnie. Do rozwiązania były następujące problemy&lt;/font&gt;: &lt;/span&gt;    &lt;br /&gt;&lt;/font&gt;  &lt;ul&gt;   &lt;li&gt;&lt;span style="font-family: trebuchet ms; font-size: 85%"&gt;&lt;font size="2"&gt;Wartości w kolumnach x i y muszą unikatowe z założeniem, że x i y mogą wielokrotnie przyjmować wartość NULL&lt;/font&gt;&lt;/span&gt; &lt;/li&gt;    &lt;li&gt;&lt;span style="font-family: trebuchet ms; font-size: 85%"&gt;&lt;font size="2"&gt;Jeżeli wartość w kolumnie x jest NULL to wartość w kolumnie y także musi być NULL i na odwrót, y może mieć wartość NULL tylko w przypadku gdy x jest NULL&lt;/font&gt;&lt;/span&gt; &lt;/li&gt; &lt;/ul&gt; &lt;span style="font-family: trebuchet ms; font-size: 85%"&gt;&lt;font size="2"&gt;Poniższy fragment kodu posży nam do utworzenia przykładowych tabel.      &lt;br /&gt;&lt;/font&gt;    &lt;br /&gt;&lt;/span&gt;&lt;font size="2"&gt;&lt;font color="#474b4e"&gt;&lt;span style="font-family: courier new; color: #009900; font-size: 85%"&gt;&lt;font size="2"&gt;IF OBJECT_ID('SOURCES') IS NOT NULL          &lt;br /&gt;DROP TABLE SOURCES           &lt;br /&gt;GO           &lt;br /&gt;          &lt;br /&gt;CREATE TABLE SOURCES (           &lt;br /&gt;SOURCE_ID INT NOT NULL primary key,           &lt;br /&gt;SOURCE_NAME NVARCHAR(100) NOT NULL           &lt;br /&gt;)           &lt;br /&gt;GO           &lt;br /&gt;          &lt;br /&gt;INSERT INTO SOURCES           &lt;br /&gt;SELECT '1', 'Source 1' UNION           &lt;br /&gt;SELECT '2', 'Source 2'           &lt;br /&gt;GO           &lt;br /&gt;          &lt;br /&gt;IF OBJECT_ID('ARTICLES') IS NOT NULL           &lt;br /&gt;DROP TABLE ARTICLES           &lt;br /&gt;GO           &lt;br /&gt;          &lt;br /&gt;CREATE TABLE ARTICLES (           &lt;br /&gt;ID INT IDENTITY NOT NULL PRIMARY KEY,           &lt;br /&gt;TITLE NVARCHAR(100) NOT NULL,           &lt;br /&gt;FOREIGN_ID NVARCHAR(10) NULL,           &lt;br /&gt;SOURCE_ID INT NULL,           &lt;br /&gt;CONSTRAINT FK_AS FOREIGN KEY(SOURCE_ID) REFERENCES SOURCES(SOURCE_ID)           &lt;br /&gt;)&lt;/font&gt;         &lt;br /&gt;&lt;/span&gt;      &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;span style="font-family: trebuchet ms; font-size: 85%"&gt;&lt;font size="2"&gt;Postawione wcześniej warunki odnoszą się do kolumn FOREIGN_ID oraz SOURCE_ID w tabeli ARTICLES.      &lt;br /&gt;      &lt;br /&gt;&lt;/font&gt;&lt;font size="2"&gt;Pierwszym orzechem do zgryzienia był problem zapewnienia by FOREIGN_ID oraz SOURCE_ID były unikatowe, jednakże dopuszczalna jest sytuacja, gdy artykuł nie posiada żadnego źródła. Na początku pomyślałem, że UNIQUE Cosntraint rozwiąże problem, ale od razu zapaliła mi się w głowie lampka. Te rozwiązanie zadziałałoby tylko dla pierwszego rekordu z podaną kombinacją danych a to nie było to czego potrzebowałem. Tak więc skorzystać musiałem z innego rozwiązania.&lt;/font&gt;     &lt;br /&gt;&lt;/span&gt;  &lt;h3&gt;&lt;span style="font-family: trebuchet ms"&gt;Unikatowy indeks na kolumnach zawierających wartoci NULL&lt;/span&gt;&lt;/h3&gt; &lt;font size="2"&gt;&lt;span style="font-family: trebuchet ms; font-size: 85%"&gt;&lt;font size="2"&gt;SQL Server 2008 umożliwia zakładanie indeksów zawierających filter. Filtrem w tym przypadku była wartość NULL w obu kolumnach&lt;/font&gt;.       &lt;br /&gt;&lt;/span&gt;    &lt;br /&gt;&lt;/font&gt;&lt;span style="font-family: courier new"&gt;&lt;span style="font-size: 85%"&gt;&lt;span style="color: #009900"&gt;&lt;font size="2"&gt;CREATE UNIQUE INDEX IDX_UNIQUE ON ARTICLES(FOREIGN_ID, SOURCE_ID)          &lt;br /&gt;WHERE FOREIGN_ID IS NOT NULL AND SOURCE_ID IS NOT NULL           &lt;br /&gt;&lt;/font&gt;&lt;/span&gt;      &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: trebuchet ms; font-size: 85%"&gt;&lt;font size="2"&gt;Tak zadeklarowany indeks sprawi, że będzie on składał się tylko z tych rekordów, które przyjmują wartości w obu kolumnach&lt;/font&gt;.     &lt;br /&gt;    &lt;br /&gt;&lt;font size="2"&gt;Poniższe zapytania przetestują utworzony indeks      &lt;br /&gt;&lt;/font&gt;&lt;/span&gt;  &lt;br /&gt;&lt;font color="#474b4e"&gt;&lt;font size="2"&gt;&lt;span style="font-family: courier new; color: #009900; font-size: 85%"&gt;&lt;font size="2"&gt;insert into articles (title)          &lt;br /&gt;select 'Article 1' union           &lt;br /&gt;select 'Article 2'&lt;/font&gt;         &lt;br /&gt;        &lt;br /&gt;&lt;font size="2"&gt;insert into articles (title, foreign_id, source_id)          &lt;br /&gt;select 'Article 3', '1', 1 union           &lt;br /&gt;select 'Article 4', '1', 1&lt;/font&gt;         &lt;br /&gt;&lt;/span&gt;      &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;span style="font-family: trebuchet ms; font-size: 85%"&gt;&lt;font size="2"&gt;Pierwszy INSERT wykona się bez błędów, natomiast drugi zwróci następujący błąd      &lt;br /&gt;&lt;/font&gt;    &lt;br /&gt;&lt;span style="font-family: courier new; color: #ff0000"&gt;&lt;font size="2"&gt;Cannot insert duplicate key row in object 'dbo.ARTICLES' with unique index 'IDX_UNIQUE'.        &lt;br /&gt;&lt;/font&gt;&lt;/span&gt;    &lt;br /&gt;&lt;font size="2"&gt;Tak więc pierwszy problem został rozwiązany. Pozostaje jeszcze drugi aby rekordy nie zawierały źródła i klucza obcego, lub też by zawierały obie wartości jednocześnie. &lt;/font&gt;&lt;/span&gt;  &lt;br /&gt;  &lt;h3&gt;&lt;span style="font-family: trebuchet ms"&gt;Wartość NULL w kolumnie z warunkiem&lt;/span&gt;&lt;/h3&gt;  &lt;p&gt;&lt;span style="font-family: trebuchet ms; font-size: 85%"&gt;&lt;font size="2"&gt;Tutaj z pomocą przychodzi CHECK constraint. Umożliwia on dodanie danych, tylko w przypadku spełnienia jakiegoś warunku&lt;/font&gt;.       &lt;br /&gt;      &lt;br /&gt;&lt;font size="2"&gt;W tym przypadku warunkiem jest, że albo obie kolumny przyjmują wartość NULL albo żadna z nich.        &lt;br /&gt;&lt;/font&gt;&lt;/span&gt;    &lt;br /&gt;&lt;font color="#474b4e"&gt;&lt;font size="2"&gt;&lt;span style="font-family: courier new; color: #009900; font-size: 85%"&gt;&lt;font size="2"&gt;ALTER TABLE ARTICLES ADD CHECK ((FOREIGN_ID IS NULL AND SOURCE_ID IS NULL) OR (FOREIGN_ID IS NOT NULL AND SOURCE_ID IS NOT NULL))&lt;/font&gt;           &lt;br /&gt;&lt;/span&gt;        &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span style="font-family: trebuchet ms; font-size: 85%"&gt;Powyższy fragment kodu spełni postawiony wcześniej warunek.        &lt;br /&gt;        &lt;br /&gt;Z kolei poniższe 3 zapytania przetestują, czy wszystko działa tak jak powinno         &lt;br /&gt;&lt;/span&gt;      &lt;br /&gt;&lt;/font&gt;&lt;span style="font-family: courier new; color: #009900; font-size: 85%"&gt;&lt;font size="2"&gt;insert into articles (title, foreign_id, source_id) values ('Article 3', NULL, 1)&lt;/font&gt;&lt;font size="2"&gt;        &lt;br /&gt;        &lt;br /&gt;&lt;font size="2"&gt;insert into articles (title, foreign_id, source_id) values ('Article 3', '1', NULL)&lt;/font&gt;         &lt;br /&gt;        &lt;br /&gt;&lt;font size="2"&gt;insert into articles (title, foreign_id, source_id) values ('Article 3', '1', 1)&lt;/font&gt;         &lt;br /&gt;&lt;/font&gt;      &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: trebuchet ms; font-size: 85%"&gt;&lt;font size="2"&gt;Pierwsze dwa zapytania zwrócą nastepujący błąd. Jedna z kolumn przyjmuje wartość NULL        &lt;br /&gt;        &lt;br /&gt;&lt;/font&gt;&lt;font color="#474b4e"&gt;&lt;font size="2"&gt;&lt;span style="font-family: courier new; color: #ff0000"&gt;The INSERT statement conflicted with the CHECK constraint &amp;quot;CK__ARTICLES__1D7B6025&amp;quot;. The conflict occurred in database &amp;quot;tempdb&amp;quot;, table &amp;quot;dbo.ARTICLES&amp;quot;            &lt;br /&gt;&lt;/span&gt;          &lt;br /&gt;Natomiast ostatnie zapytanie pomyślnie zostanie wykonane.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;Na koniec jeszcze krótki fragment kodu, który usunie utworzone wcześniej tabele.&lt;/p&gt; &lt;font color="#009900" face="Courier New"&gt;IF OBJECT_ID('ARTICLES') IS NOT NULL    &lt;br /&gt;DROP TABLE ARTICLES     &lt;br /&gt;GO     &lt;br /&gt;    &lt;br /&gt;IF OBJECT_ID('SOURCES') IS NOT NULL     &lt;br /&gt;DROP TABLE SOURCES     &lt;br /&gt;GO     &lt;br /&gt;&lt;/font&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-4795917022943001135?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/Ph9xpEAepWQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/4795917022943001135/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=4795917022943001135" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/4795917022943001135?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/4795917022943001135?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/Ph9xpEAepWQ/intregralnosc-danych-i-wartosci-null.html" title="Intregralność danych i wartości NULL" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2011/09/intregralnosc-danych-i-wartosci-null.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQASXo_cCp7ImA9WhdSGE0.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-7328072018531395935</id><published>2011-07-27T18:17:00.012+02:00</published><updated>2011-07-27T23:32:28.448+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-27T23:32:28.448+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="T-SQL" /><title>DELETE z klauzulą OUTPUT a integralność danych</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/twa_hnFvvOh5nNsR1yU1AlGltaA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/twa_hnFvvOh5nNsR1yU1AlGltaA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/twa_hnFvvOh5nNsR1yU1AlGltaA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/twa_hnFvvOh5nNsR1yU1AlGltaA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span class="Apple-style-span"   style="font-family:trebuchet ms;font-size:85%;"&gt;Dzisiaj natrafiłem na ciekawą właściwość klauzuli OUTPUT. Miałem za zadanie napisać procedurę, która usuwa rekord z jednej tabeli i zapisuje go to innej. Prosty audyt, bez wykorzystywania triggerów.&lt;/span&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Problem trywialny. Stworzyłem sobie tabelę do której zapisywane są usuwane recordy. Do tego dodałem kilka kluczy obcych. W zapytaniu, które usuwa recordy dodałem klauzulę OUTPUT, tak by zapisać skasowane dane do mojej nowej tabeli. Proste, nieprawdaż? Otóż nie. W momencie uruchomienia mojej procedure od razu sie ona wysypała. Niestety w klauzuli OUTPUT ... INSERT nie może występować tabela, która jest powiązana z innymi tabelami kluczami obcymi. I co tu wybrać teraz integralnośćdanych czy wygodę?&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Wole integralność mimo wszystko kosztem bardziej złożonego zapytania. Tyle teorii, teraz praktyka. Poniższy przykład w bardzo prosty sposób pokazuje istotę problemu.&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Najpierw tabele:&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="color: rgb(0, 153, 0); font-family: courier new;font-family:trebuchet ms;"&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;USE TEMPDB&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;CREATE TABLE PRODUCTS (&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;ID INT IDENTITY NOT NULL PRIMARY KEY,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[DESCRIPTION] NVARCHAR(100)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;CREATE TABLE PROFILES (&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;PROFILE_ID INT IDENTITY NOT NULL PRIMARY KEY,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;FULLNAME NVARCHAR(100)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;CREATE TABLE PRODUCTS_ARCHIVE (&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;ID INT IDENTITY NOT NULL PRIMARY KEY,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[DESCRIPTION] VARCHAR(100),&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;DELETEDBY INT,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;ORIGINAL_ID INT&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Teraz trochę danych testowych.&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new;font-family:trebuchet ms;" &gt;&lt;div style="color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;INSERT INTO PRODUCTS([DESCRIPTION])&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'Brick' UNION&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'Knife' UNION&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'Spanner' UNION&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'Nails'&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;INSERT INTO PROFILES (FULLNAME)&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'John Peacock' UNION&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'Steven Smith' UNION&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'Jason Brown'&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Teraz dwie procedure, które pomogą zobrazować problem.&lt;/span&gt;&lt;/div&gt;&lt;div  style="color: rgb(0, 153, 0); font-family: courier new;font-family:trebuchet ms;"&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;CREATE PROCEDURE SP_DELETE_PRODUCT&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;@ID INT,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;@DELETEDBY INT&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;AS&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;DELETE FROM PRODUCTS&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;OUTPUT DELETED.[DESCRIPTION], @DELETEDBY, DELETED.ID INTO PRODUCTS_ARCHIVE([DESCRIPTION],DELETEDBY,ORIGINAL_ID)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;WHERE ID = @ID&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;CREATE PROCEDURE SP_DELETE_PRODUCT_ALT&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;@ID INT,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;@DELETEDBY INT&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;AS&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;DECLARE @TAB TABLE (&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;[DESCRIPTION] VARCHAR(100),&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;ORIGINAL_ID INT&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;DELETE FROM PRODUCTS&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;OUTPUT DELETED.[DESCRIPTION], DELETED.ID INTO @TAB([DESCRIPTION],ORIGINAL_ID)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;WHERE ID = @ID&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre;font-size:85%;" &gt;&lt;span class="Apple-style-span"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;INSERT INTO PRODUCTS_ARCHIVE([DESCRIPTION],DELETEDBY,ORIGINAL_ID)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;SELECT [DESCRIPTION], @DELETEDBY, ORIGINAL_ID FROM @TAB&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Żadna z tabel nie jest powiązana kluczami obcymi, przeważnie niezbyt dobre to rozwiązanie.&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="color: rgb(0, 153, 0); font-family: courier new;font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;EXEC SP_DELETE_PRODUCT 1,1&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Wykonując pierwszą procedurę, która wykonuje zadanie z wykorzystaniem zaledwie 3 lini kodu otrzymujemy pożądany rezultat. Rekord został usunięty z tabeli PRODUCTS i dodany do PRODUCTS_ARCHIVE. Wszystko pięknie, ładnie i przyjemnie ale przydałoby się zapewnienie trochę integralności danch.&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;W tym celu połączymy tabele PROFILES and PRODUCTS_ARCHIVE kluczem obcym.&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="color: rgb(0, 153, 0); font-family: courier new;font-family:trebuchet ms;"&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;ALTER TABLE PRODUCTS_ARCHIVE&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;ADD CONSTRAINT FK_P_PA FOREIGN KEY(DELETEDBY) REFERENCES PROFILES(PROFILE_ID)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Teraz poniższe zapytanie zwróci błąd.&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="color: rgb(0, 153, 0); font-family: courier new;font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;EXEC SP_DELETE_PRODUCT 2,1&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style=" color: rgb(255, 0, 0);font-family:trebuchet ms;"&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Msg 332, Level 16, State 1, Procedure SP_DELETE_PRODUCT, Line 6&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;The target table 'PRODUCTS_ARCHIVE' of the OUTPUT INTO clause cannot be on either side of a (primary key, foreign key) relationship. Found reference constraint 'FK_P_PA'.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Niestety DELETE ... INTO &lt;tabla&gt; nie lubi relacji między tabelami.&lt;/tabla&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Rozwiązaniem problemu w tym przypadku jest utworzenie tabeli tymczasowej lub zmiennej w celu przechowania usuwanych danych.&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Problem można rozwiązać na dwa sposoby. Albo wykonać zapytanie SELECT, które skopiuje usuwane dane do tabeli tymczasowej, przed wykonaniem polecenia DELETE, albo też skorzystać z klauzuli OUTPUT ... INTO.&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Mając już usunięte dane z pierwszej tabeli, należy teraz skopiować zawartość tabeli tymczasowej do tabeli docelowej. &lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Te rozwiązanie wykorzystuje druga procedura, poniższe zapytanie wykona sie bez błędów.&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="color: rgb(0, 153, 0); font-family: courier new;font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;EXEC SP_DELETE_PRODUCT_ALT 2,1&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Na koniec jeszcze dla formalności troche kodu czyszczącego utworzone obiekty.&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:trebuchet ms;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="color: rgb(0, 153, 0); font-family: courier new;font-family:trebuchet ms;"&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;DROP PROCEDURE SP_DELETE_PRODUCT&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;DROP PROCEDURE SP_DELETE_PRODUCT_ALT&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;DROP TABLE PRODUCTS_ARCHIVE&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;DROP TABLE PRODUCTS&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;DROP TABLE PROFILES&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GO&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-7328072018531395935?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/LSOqCdFmP6A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/7328072018531395935/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=7328072018531395935" title="Komentarze (1)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/7328072018531395935?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/7328072018531395935?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/LSOqCdFmP6A/delete-z-klauzula-output-integralnosc.html" title="DELETE z klauzulą OUTPUT a integralność danych" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2011/07/delete-z-klauzula-output-integralnosc.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYMRX0yeip7ImA9WhZUEE8.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-4843355608498134613</id><published>2011-06-02T02:28:00.010+02:00</published><updated>2011-06-02T15:59:44.392+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-02T15:59:44.392+02:00</app:edited><title>Wartość minimalna nie mniejsza niż...</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/s8PBt0qxIlHPhg_Ebi0b4In4sME/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/s8PBt0qxIlHPhg_Ebi0b4In4sME/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/s8PBt0qxIlHPhg_Ebi0b4In4sME/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/s8PBt0qxIlHPhg_Ebi0b4In4sME/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-family: verdana;font-size:85%;" class="Apple-style-span" &gt;Czy zastanawialiście sie kiedys jak znaleść najmniejszą wartość w zbiorze, jednakże tak była ona większa od pewnej wartości a w dodatku by rozwiązanie to było dobrze zoptymalizowane?&lt;/span&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Problem można rozwiązać na kilka sposobów. &lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Pierwsza rzecz jaka kazdemu przychodzi zapewne do głowy to:&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="color: rgb(0, 153, 0); font-family: courier new;font-family:courier new;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT ID, MIN(COL) FROM MyTABLE WHERE COL &amp;gt;  x GROUP BY ID&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Cel osiągniety bez większego nakładu sił. Co jednak w przypadku kiedy potrzebne są wartości minimalne dla kilku kolumn?&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Można to zrobić na kilka sposobów pewnie. Żeby nie teoretyzować za dużo poniższe rozwiązanie wykorzystuje fragment notowań dwóch spółek z GPW.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Przykładowa dane zapiszemy w tabeli tymczasowej&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SET NOCOUNT ON&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;IF OBJECT_ID('TEMPDB..#QUOTES') IS NOT NULL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;DROP TABLE #QUOTES&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;;WITH CTE AS (&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL' AS NAZWA,'04 May 201' AS DATE,0 AS VOLUME, 0.00 AS VALUE, 0 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','05 May 201' AS DATE,0 AS VOLUME, 0.00 AS VALUE, 0 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','06 May 201' AS DATE,0 AS VOLUME, 0.00 AS VALUE, 0 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','09 May 201' AS DATE,0 AS VOLUME, 0.00 AS VALUE, 0 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','10 May 201' AS DATE,0 AS VOLUME, 0.00 AS VALUE, 0 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','11 May 201' AS DATE,187000 AS VOLUME, 41140.00 AS VALUE, 24 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','12 May 201' AS DATE,345662 AS VOLUME, 90760.00 AS VALUE, 36 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','13 May 201' AS DATE,268563 AS VOLUME, 99930.00 AS VALUE, 51 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','16 May 201' AS DATE,765218 AS VOLUME, 425420.00 AS VALUE, 263 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','17 May 201' AS DATE,378111 AS VOLUME, 307780.00 AS VALUE, 170 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','18 May 201' AS DATE,1502701 AS VOLUME, 1485030.00 AS VALUE, 833 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','19 May 201' AS DATE,1397675 AS VOLUME, 1441540.00 AS VALUE, 784 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','20 May 201' AS DATE,191155 AS VOLUME, 203610.00 AS VALUE, 132 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','23 May 201' AS DATE,159533 AS VOLUME, 152170.00 AS VALUE, 132 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','24 May 201' AS DATE,204692 AS VOLUME, 173250.00 AS VALUE, 139 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','25 May 201' AS DATE,246006 AS VOLUME, 187250.00 AS VALUE, 152 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','26 May 201' AS DATE,175840 AS VOLUME, 151150.00 AS VALUE, 113 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','27 May 201' AS DATE,113403 AS VOLUME, 92440.00 AS VALUE, 87 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','30 May 201' AS DATE,221718 AS VOLUME, 176730.00 AS VALUE, 149 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'URLOPYPL','31 May 201' AS DATE,669521 AS VOLUME, 679490.00 AS VALUE, 383 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','04 May 201' AS DATE,991 AS VOLUME, 496280.00 AS VALUE, 23 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','05 May 201' AS DATE,537 AS VOLUME, 267640.00 AS VALUE, 13 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','06 May 201' AS DATE,966 AS VOLUME, 474170.00 AS VALUE, 29 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','09 May 201' AS DATE,1390 AS VOLUME, 682390.00 AS VALUE, 22 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','10 May 201' AS DATE,89 AS VOLUME, 44370.00 AS VALUE, 8 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','11 May 201' AS DATE,57 AS VOLUME, 28430.00 AS VALUE, 15 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','12 May 201' AS DATE,286 AS VOLUME, 140850.00 AS VALUE, 23 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','13 May 201' AS DATE,367 AS VOLUME, 183830.00 AS VALUE, 24 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','16 May 201' AS DATE,79 AS VOLUME, 39590.00 AS VALUE, 11 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','17 May 201' AS DATE,946 AS VOLUME, 466280.00 AS VALUE, 18 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','18 May 201' AS DATE,0 AS VOLUME, 0.00 AS VALUE, 0 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','19 May 201' AS DATE,144 AS VOLUME, 72630.00 AS VALUE, 9 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','20 May 201' AS DATE,1412 AS VOLUME, 713060.00 AS VALUE, 10 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','23 May 201' AS DATE,1727 AS VOLUME, 856060.00 AS VALUE, 26 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','24 May 201' AS DATE,70 AS VOLUME, 34580.00 AS VALUE, 9 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','25 May 201' AS DATE,20 AS VOLUME, 9860.00 AS VALUE, 1 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','26 May 201' AS DATE,0 AS VOLUME, 0.00 AS VALUE, 0 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','27 May 201' AS DATE,38 AS VOLUME, 18740.00 AS VALUE, 5 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','30 May 201' AS DATE,0 AS VOLUME, 0.00 AS VALUE, 0 AS TRANSACTIONS UNION ALL&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT 'WAWEL','31 May 201' AS DATE,526 AS VOLUME, 262780.00 AS VALUE, 16 AS TRANSACTIONS&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT * INTO #QUOTES FROM CTE&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;CREATE NONCLUSTERED INDEX IDX_QUOTES ON #QUOTES(NAZWA,[DATE]) INCLUDE(VOLUME, VALUE, TRANSACTIONS) &lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Powiedzmy, że potrzebujemy wartości minimalne dla ilości transakcji, wolumenu oraz wartości obrotu, jednakże tylko z sesji gdzie wystąpiły transakcje.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;NAZWA,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;MIN(TRANSACTIONS) MIN_TRANSACTIONS,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;MIN(VOLUME) MIN_VOLUME,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;MIN(VALUE) MIN_VALUE,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;'Excluded sessions without transactions' NOTES&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;FROM #QUOTES&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;WHERE TRANSACTIONS &amp;gt; 0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Powyższe zapytanie zwróci oczekiwane wyniki. Przykład jest dość trywialny, gdyż wartości w kolumnach, z który pobierane są wartości minimalne są skorelowane z ilością transakcji. Jeżeli nie bylo transakcji to zarówno wolumen jak i wartość obrotu wynoszą 0.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Powyższe zapytanie zwróci następujące wyniki:&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;NAZWA    MIN_TRANSACTIONS MIN_VOLUME  MIN_VALUE                               NOTES&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;-------- ---------------- ----------- --------------------------------------- --------------------------------------&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;URLOPYPL 24               113403      41140.00                                Excluded sessions without transactions&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;WAWEL    1                20          9860.00                                 Excluded sessions without transactions&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Przy okazji cel został osiągnięty przy jednym skanie całej tabeli.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Co jednak w przypadku gdybyśmy chcieli obliczyć dodatkowo średnią ilość transakcji, ale biorąc pod uwagę także sesje bez transakcji?&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Poniższe zapytanie, z warunkiem na ilość transakcji niestety, ale zwróci niepoprawne wyniki&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;NAZWA,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;MIN(TRANSACTIONS) MIN_TRANSACTIONS,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;MIN(VOLUME) MIN_VOLUME,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;MIN(VALUE) MIN_VALUE,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;AVG(TRANSACTIONS) AVG_TRANSACTIONS,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;'Excluded sessions without transactions' NOTES&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;FROM #QUOTES&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;WHERE TRANSACTIONS &amp;gt; 0&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GROUP BY NAZWA&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Problem można by rozwiązać za pomocą skorelowanego zapytania lub CROSS APPLY, jednakże będzie się to wiązać z dodatkowym skanem tabeli.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Czy komuś przychodzi do głowy inne rozwiązanie, takie które by zwrócilo pożądane wyniki z wykorzystaniem tylko jednego skanu tabeli?&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;Otóż z pomocą przychodzi tutaj CASE WHEN ... END.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: courier new; color: rgb(0, 153, 0);"&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;SELECT&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;NAZWA,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;MIN(CASE WHEN TRANSACTIONS = 0 THEN NULL ELSE TRANSACTIONS END) MIN_TRANSACTIONS,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;MIN(CASE WHEN VOLUME = 0 THEN NULL ELSE VOLUME END) MIN_VOLUME,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;MIN(CASE WHEN VALUE = 0 THEN NULL ELSE VALUE END) MIN_VALUE,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;AVG(TRANSACTIONS) AVG_TRANSACTIONS,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;'Included sessions without transactions' NOTES&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;FROM #QUOTES&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;GROUP BY NAZWA&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;W przypadku gdy nie wystąpiły żadne transakcje w ciągu danej sesji, funkcja agregująca przyjmuje NULL w pozostałym przypadku wartość dla danej sesji. Rozwiązanie jest to o tyle uniwersalne, że możemy pobrac wartość minimalną nie mniejszą niż, i może być to zarazem różna wartość dla każdej z kolumn.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-4843355608498134613?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/yXvGpAluVbo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/4843355608498134613/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=4843355608498134613" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/4843355608498134613?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/4843355608498134613?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/yXvGpAluVbo/wartosc-minimalna-nie-mniejsza-niz.html" title="Wartość minimalna nie mniejsza niż..." /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2011/06/wartosc-minimalna-nie-mniejsza-niz.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEENSXY7fip7ImA9WxRaEUU.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-966569356909087050</id><published>2008-12-13T17:30:00.003+01:00</published><updated>2008-12-13T17:44:58.806+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-13T17:44:58.806+01:00</app:edited><title>MCTS: Microsoft SQL Server 2008, Database Development</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hch-YOyg5A39m0pwHT3Ic0wUxEs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hch-YOyg5A39m0pwHT3Ic0wUxEs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hch-YOyg5A39m0pwHT3Ic0wUxEs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hch-YOyg5A39m0pwHT3Ic0wUxEs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;Wczoraj otrzymałem miłego maila z Microsoftu. Mój wynik beta egzaminu 71-433 został oceniony pozytywnie. Tak więc od 9 paźniernika posiadam tytuł MCTS SQL Server 2008, Database Development.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-966569356909087050?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/RKtezDPw9pA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/966569356909087050/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=966569356909087050" title="Komentarze (1)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/966569356909087050?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/966569356909087050?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/RKtezDPw9pA/mcts-microsoft-sql-server-2008-database.html" title="MCTS: Microsoft SQL Server 2008, Database Development" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2008/12/mcts-microsoft-sql-server-2008-database.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYBSHYyeip7ImA9WxRbFE4.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-8734678241121119751</id><published>2008-12-05T01:42:00.001+01:00</published><updated>2008-12-05T01:49:19.892+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-05T01:49:19.892+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ISNUMERIC" /><category scheme="http://www.blogger.com/atom/ns#" term="CLR" /><title>Czy ten łańcuch znaków jest liczbą?</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gS7IS5YNq5SQ3AD8w38GN8fozm0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gS7IS5YNq5SQ3AD8w38GN8fozm0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gS7IS5YNq5SQ3AD8w38GN8fozm0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gS7IS5YNq5SQ3AD8w38GN8fozm0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;Problem z pozoru banalny. Sprawdzenie czy łańcuch znaków jest liczbą. Jak to zrobić? Większość osób z pewnością od razu skorzystałaby z funkcji ISNUMERIC. Problem polega na tym, że ta funkcja sprawdza czy dany łańcuch jest typu numerycznego, a nie czy jest liczbą. Funkcja ISNUMERIC zwróci wartość 1 dla następujących wartości '+', '-', '101.5E9', '$10', oraz innych wartości pieniężnych zawierających odpowiednie znaki reprezentujące waluty (&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms188688.aspx"&gt;&lt;span style="font-size:85%;"&gt;http://msdn.microsoft.com/en-us/library/ms188688.aspx&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;).&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Jakie mogą być konsekwencje sprawdzania łańcucha znaków tylko za pomocą ISNUMERIC? Ano takie, że funkcja, procedura czy tam inny kod napisany w SQL się wysypie. Poniżej kilka przykładów, w których ISNUMERIC za każdym razem zawraca wartość 1.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;DECLARE @STRING AS VARCHAR(1)&lt;br /&gt;SET @STRING = '+'&lt;br /&gt;IF ISNUMERIC(@STRING) = 1&lt;br /&gt;            SELECT CONVERT(DECIMAL,@STRING) + 10&lt;br /&gt;GO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#ff0000;"&gt;Msg 8115, Level 16, State 6, Line 5&lt;br /&gt;Arithmetic overflow error converting varchar to data type numeric.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;DECLARE @STRING AS VARCHAR(3)&lt;br /&gt;SET @STRING = '$10'&lt;br /&gt;IF ISNUMERIC(@STRING) = 1&lt;br /&gt;            SELECT CONVERT(INT, @STRING) + 10&lt;br /&gt;GO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#ff0000;"&gt;Msg 245, Level 16, State 1, Line 5&lt;br /&gt;Conversion failed when converting the varchar value '$10' to data type int.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;DECLARE @STRING AS VARCHAR(10)&lt;br /&gt;SET @STRING = '101.5E9'&lt;br /&gt;IF ISNUMERIC(@STRING) = 1&lt;br /&gt;            SELECT CONVERT(INT, @STRING) + 10&lt;br /&gt;GO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#ff0000;"&gt;Msg 245, Level 16, State 1, Line 5&lt;br /&gt;Conversion failed when converting the varchar value '101.5E9' to data type int.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Jak więc sprawdzić czy łańcuch znaków jest wartością numeryczną, oraz jest typu, który pożądany jest w dalszych obliczeniach?&lt;br /&gt;&lt;br /&gt;Ano można skorzystać w tym celu np. z wyrażeń regularnych. Jako, że wyrażenia regularne nie występują póki co w SQL Server, potrzebna będzie funkcja napisana w CLR.&lt;br /&gt;&lt;br /&gt;W poprzednim poście (&lt;/span&gt;&lt;a href="http://updatedev.blogspot.com/2008/11/transformacja-wyniku-zapytania-do.html"&gt;&lt;span style="font-size:85%;"&gt;http://updatedev.blogspot.com/2008/11/transformacja-wyniku-zapytania-do.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;) zaprezentowałem bibliotekę CLTToolsSuite. Rozbuduję ją teraz o kolejną funkcję, która będzie weryfikowała łańcuch znaków za pomocą wyrażeń regularnych.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;&amp;lt;SqlFunction(isdeterministic:=True, dataaccess:=DataAccessKind.None)&amp;gt; _&lt;br /&gt;    Public Shared Function RegEx(ByVal input As SqlString, ByVal pattern As SqlString) As SqlBoolean&lt;br /&gt;        Dim RegExpr As New Regex(pattern)&lt;br /&gt;        Dim match As Match&lt;br /&gt;&lt;br /&gt;        If input.IsNull Or pattern.IsNull Then&lt;br /&gt;            Return False&lt;br /&gt;        End If&lt;br /&gt;&lt;br /&gt;        match = RegExpr.Match(input)&lt;br /&gt;        If match.Success Then&lt;br /&gt;            Return True&lt;br /&gt;        Else&lt;br /&gt;            Return False&lt;br /&gt;        End If&lt;br /&gt;    End Function&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Funkcja ta akceptuje dwa parametry. Łańcuch znaków do zweryfikowania oraz szablon wyrażenia regularnego. W przypadku gdy łańcuch znaków jest poprawny funkcja zwraca 1, w każdym innym przypadku 0.&lt;br /&gt;&lt;br /&gt;Po skompilowaniu biblioteki pora ja zarejestrować i utworzyć nową funkcję.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;IF OBJECT_ID('fn_RegEx') IS NOT NULL&lt;br /&gt;            drop function fn_RegEx&lt;br /&gt;&lt;br /&gt;IF EXISTS(SELECT * FROM sys.assemblies WHERE name = 'CLRToolsSuite')&lt;br /&gt;            drop assembly CLRToolsSuite&lt;br /&gt;go&lt;br /&gt;&lt;br /&gt;CREATE ASSEMBLY CLRToolsSuite&lt;br /&gt;from 'C:\CLRToolsSuite\CLRToolsSuite\bin\Release\CLRToolsSuite.dll'&lt;br /&gt;WITH PERMISSION_SET = SAFE;&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;CREATE FUNCTION dbo.fn_RegEx(@input as nvarchar(max), @pattern as nvarchar(max))&lt;br /&gt;RETURNS BIT&lt;br /&gt;EXTERNAL name CLRToolsSuite.[CLRToolsSuite.CLRToolsSuite].RegEx;&lt;br /&gt;GO&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;I teraz krótki test, w którym funkcja ISNUMERIC została zastąpiona przez nową funkcję fn_RegEx.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;DECLARE @STRING AS VARCHAR(5)&lt;br /&gt;SET @STRING = '+'&lt;br /&gt;IF dbo.fn_RegEx(@STRING, '^[0-9]+(\.*[0-9]*)$') = 1&lt;br /&gt;            SELECT CONVERT(DECIMAL,@STRING) + 10&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;DECLARE @STRING AS VARCHAR(5)&lt;br /&gt;SET @STRING = '$10'&lt;br /&gt;IF dbo.fn_RegEx(@STRING, '^[0-9]+$') = 1&lt;br /&gt;            SELECT CONVERT(INT,@STRING) + 10&lt;br /&gt;GO     &lt;br /&gt;&lt;br /&gt;DECLARE @STRING AS VARCHAR(10)&lt;br /&gt;SET @STRING = '101.5E9'&lt;br /&gt;IF dbo.fn_RegEx(@STRING, '^[0-9]+$') = 1&lt;br /&gt;            SELECT CONVERT(INT,@STRING) + 10&lt;br /&gt;GO&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Jak widać z powyższych fragmentów kodu coś co może na pierwszy rzut oka wydawać się banalne, wcale takim w rzeczywistości być nie musi. Warto pamiętać więc co funkcja ISNUMERIC robi i jakie są jej ograniczenia.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-8734678241121119751?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/yeIzsYD4QEA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/8734678241121119751/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=8734678241121119751" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/8734678241121119751?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/8734678241121119751?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/yeIzsYD4QEA/czy-ten-acuch-znakw-jest-liczb.html" title="Czy ten łańcuch znaków jest liczbą?" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2008/12/czy-ten-acuch-znakw-jest-liczb.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4ESHY8cSp7ImA9WxRVFEk.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-5989848299623506487</id><published>2008-11-11T23:58:00.005+01:00</published><updated>2008-11-12T00:58:29.879+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-12T00:58:29.879+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XSL" /><category scheme="http://www.blogger.com/atom/ns#" term="xml" /><category scheme="http://www.blogger.com/atom/ns#" term="CLR" /><title>Transformacja wyniku zapytania do innego formatu</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Bgjlz8Iy9YRhFeTJps8f7vI4Zmc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Bgjlz8Iy9YRhFeTJps8f7vI4Zmc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Bgjlz8Iy9YRhFeTJps8f7vI4Zmc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Bgjlz8Iy9YRhFeTJps8f7vI4Zmc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;Dzisiaj zajmę się tematem formatowania wyniku zapytania. Czasami zachodzi potrzeba aby wynik zapytania był w jakimś formacie, który łatwiej umożliwia wizualizację danych. Tym formatem może być HTML, XHTML. W poście tym przedstawię dwie techniki formatowania / transformowania wyniku zapytania.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:85%;color:#993300;"&gt;HTML w T-SQL&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Pierwszą z technik, którą przedstawię zaprezentował na swoim &lt;a href="http://sqlblogcasts.com/blogs/tonyrogerson/archive/2008/10/24/format-query-output-into-an-html-table-the-easy-way.aspx"&gt;blogu&lt;/a&gt; Tony Rogerson. Bardzo ciekawa technika umożliwiająca otrzymanie wyniku zapytania jako dokumentu HTML. Poniższe zapytanie korzysta z bazy danych Northwind.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;declare @body varchar(max)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;set @body = cast( (&lt;br /&gt;select 'company_name' as "&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;td/@class&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;",td = CompanyName + '&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;' + ContactName + '&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;' + ContactTitle + '&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;' + Address +'&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;' + City + '&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;' + PostalCode + '&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;' + Country&lt;br /&gt;from (&lt;br /&gt;select CompanyName, ContactName, ContactTitle, Address, City, PostalCode, Country &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;from customers&lt;br /&gt;) as d&lt;br /&gt;for xml path( 'tr' ), type ) as varchar(max) )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;set @body = '&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;style&amp;gt;'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;+ 'TABLE {border: 1px; width:600px}'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;+ 'TH {border-bottom: 5px solid red; border-top: 5px solid black; white-space:nowrap}'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;+ 'TD {font-size: 12px; font-family:verdana; white-space: nowrap}'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;+ '.table_header {font-family: Verdana; font-size: 14px;}'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;+ '.company_name {color:black; font-weight:bold;}'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;+ '&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;+ '&amp;lt;h2&amp;gt;Northwind Customers&amp;lt;/h2&amp;gt;&amp;lt;table cellspacing="0"&amp;gt;'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;+'&amp;lt;trclass="table_header"&amp;gt;&amp;lt;th&amp;gt;CompanyName&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;ContactName&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Title&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Address&amp;lt;/th&amp;gt;'&lt;/span&gt; &lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;+'&amp;lt;th&amp;gt;City&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;PostalCode&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Country&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;'&lt;/span&gt; &lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;+ replace( replace( @body, '&amp;amp;lt;', '&amp;lt;' ), '&amp;amp;gt;', '&amp;gt;' ) + '&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Powyższe zapytanie tworzy łańcuch znaków, będący dokumentem HTML. Jak widać poza znacznikami, można też utworzyć style CSS, które formatują dokument.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Aby zobaczyć dokument wynikowy wystarczy wykonać poniższe zapytanie.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;select CONVERT(xml, @body)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Technika ta wykorzystuje tylko i wyłącznie T-SQL. Wszystkie znaczniki oraz style są umieszczone w łańcuchach znaków. Nie ma potrzeby odwołań do zewnętrznych komponentów. Minusem tej techniki jest to, że w przypadku bardziej skomplikowanego dokumentu można bardzo łatwo zapomnieć o domknięciu jakiego znacznika. Poza tym czytelność zapytania także ulega degradacji wraz ze wzrostem jego objętości.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#993300;"&gt;&lt;strong&gt;HTML z użyciem CLR, XML, XSLT&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ten sam rezultat można otrzymać korzystając z innej techniki, a mianowicie zwrócić wynik zapytania jako dokument XML i wykonać na nim transformaty za pomocą XSLT. Jako, że SQL Server nie umożliwia wykonania tego typu operacji należy skorzystać z możliwości jakie niesie ze sobą CLR.&lt;br /&gt;&lt;br /&gt;W celu wykonania transformacji utworzę funkcję, która jako parametry będzie przyjmowała dokument XML, dokument XSLT. Funkcja ta zwracać będzie dokument w innym formacie. Celowo użyłem sformułowania „w innym formacie”, gdyż wartością zwróconą przez tą funkcję nie musi być dokument HTML. Kilka słów więcej na ten temat będzie na zakończenie artykułu.&lt;br /&gt;&lt;br /&gt;Tak więc korzystając z Visual Studio, tworzę nowy projekt, którym jest nowa klasa.&lt;br /&gt;&lt;br /&gt;Poniżej cały kod klasy, napisanej w VB.NET, zawierającej funkcję, która transformuje wynik zapytania.&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Imports System&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Imports System.Data.SqlTypes&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Imports System.IO&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Imports System.Xml&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Imports System.Xml.xsl&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Imports Microsoft.SqlServer.Server&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Partial Public Class CLRToolsSuite&lt;br /&gt;&amp;lt;SqlFunction(isdeterministic:=True, DataAccess:=DataAccessKind.None)&amp;gt; _ &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Public Shared Function XSLTransform(ByVal xmlDoc As SqlXml, ByVal xslDoc As SqlXml) As SqlXml&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Dim memory_stream As New MemoryStream()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Dim lxmlDoc As New XmlDocument&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Dim lxslTransform As New XslCompiledTransform&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Dim lxmlWriter As New XmlTextWriter(memory_stream, System.Text.Encoding.UTF8)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Dim xmlReader As XmlTextReader&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;lxmlDoc.InnerXml = xmlDoc.Value&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;lxslTransform.Load(xslDoc.CreateReader)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;lxslTransform.Transform(lxmlDoc, lxmlWriter)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;memory_stream.Seek(0, SeekOrigin.Begin)&lt;br /&gt;xmlReader = New XmlTextReader(memory_stream)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;Return New SqlXml(xmlReader)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;End Function&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;End Class&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Teraz potrzeba tylko skompilować projekt. Mając utworzoną bibliotekę .dll możemy ją zarejestrować w SQL Server.&lt;br /&gt;&lt;br /&gt;Na początek jednak trzeba włączyć możliwość korzystania z CLR. Domyślnie ta usługa, zresztą tak samo jak wiele innych rzeczy, w SQL Server jest wyłączona.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;exec sp_configure 'clr enabled', 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;RECONFIGURE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;GO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Mając włączony CLR można już zarejestrować naszą bibliotekę a także zadeklarować nową funkcję.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;CREATE ASSEMBLY CLRToolsSuite&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;from 'C:\CLRToolsSuite\CLRToolsSuite\bin\Release\CLRToolsSuite.dll'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;WITH PERMISSION_SET = SAFE;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;GO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;CREATE FUNCTION dbo.fn_XSLTransform(@xmldoc as xml, @xsldoc as xml)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;RETURNS XML&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;EXTERNAL name CLRToolsSuite.[CLRToolsSuite.CLRToolsSuite].XSLTransform;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;GO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ostatnim elementem, no poza samym zapytaniem, tej układanki jest dokument zawierający style potrzebne do przekształcenia wyniku zapytania.&lt;br /&gt;&lt;br /&gt;Nie chcę w tym miejscu wgłębiać się w XSLT. Temat ten mógłby zająć prawdopodobnie kilkanaście artykułów. Poniżej kod dokumentu XSLT, który przekształci wynik zapytania do dokumentu HTML, takiego samego jak zaprezentowany został w poprzedniej technice.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;&amp;lt;xsl:stylesheet version="1.0"xmlns:xsl="&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;http://www.w3.org/1999/XSL/Transform"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;color:#006600;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;xsl:template match="/"&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;color:#006600;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;html&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;style&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;TABLE {border: 1px; width:600px; padding: 2px;} &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;TH {border-bottom: 5px solid red; border-top: 5px solid black; white-space: nowrap} &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;TD {font-size: 12px; font-family:verdana; white-space: nowrap} &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;.table_header {font-family: Verdana; font-size: 14px;} &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;.company_name {color:black; font-weight:bold;} &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/style&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/head&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;color:#006600;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;body&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;h2&amp;gt;Northwind Customers&amp;lt;/h2&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;table cellspacing="0"&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;tr class="table_header"&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;th&amp;gt;Company Name&amp;lt;/th&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;th&amp;gt;Contact Name&amp;lt;/th&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;th&amp;gt;Title&amp;lt;/th&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;th&amp;gt;Address&amp;lt;/th&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;th&amp;gt;City&amp;lt;/th&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;th&amp;gt;Postal Code&amp;lt;/th&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;th&amp;gt;Country&amp;lt;/th&amp;gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/tr&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;color:#006600;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;xsl:for-each select="xmldoc/row"&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;tr&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;td class="company_name"&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;xsl:value-of select="CompanyName"/&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/td&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;td&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;xsl:value-of select="ContactName"/&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/td&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;td&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;xsl:value-of select="ContactTitle"/&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/td&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;td&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;xsl:value-of select="Address"/&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/td&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;td&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;xsl:value-of select="City"/&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/td&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;td&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;xsl:value-of select="PostalCode"/&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/td&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;td&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;xsl:value-of select="Country"/&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/td&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/tr&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/xsl:for-each&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/table&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/body&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/html&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/xsl:template&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;&amp;lt;/xsl:stylesheet&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;color:#006600;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;Tak oto stworzony dokument zapiszę do pliku .xslt. Równie dobrze można by go zapisać gdzieś w jakiejś tabeli w bazie danych, jednakże na potrzeby tego artykułu skorzystam z pliku, który później będzie załadowany do zmiennej.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;I teraz już pora przejść do SQL-a i wykonać zapytanie.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#006600;"&gt;DECLARE @XMLDOC AS XML&lt;br /&gt;SELECT @XMLDOC = (SELECT CompanyName, ContactName, ContactTitle, Address, City, PostalCode, CountryFROM Customers FOR XML PATH('row'), ROOT('xmldoc'))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;DECLARE @xsldoc AS XMLselect @xsldoc = xd from openrowset(BULK 'c:\xsl.xsl', SINGLE_BLOB) as import(xd)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;&lt;br /&gt;I ponownie, aby zobaczyć rezultat wystarczy wykonać jeszcze jedno zapytanie.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#006600;"&gt;select dbo.fn_XSLTransform(@xmldoc,@xsldoc)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#993300;"&gt;&lt;strong&gt;Podsumowanie&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Zarówno pierwsza jak i druga zaprezentowana technika pozwala nam uzyskać zapytanie sformatowane w postaci kodu HTML. O ile w pierwszej technice wykorzystany był tylko T-SQL o tyle druga wykorzystuje CLR i XSLT. Tak jak już wspomniałem w przypadku wykorzystania techniki tylko z T-SQL nie trudno jest o dopuszczenie się błędu w trakcie pisania znaczników HTML. W przypadku drugiej techniki, pomimo tego, że dokument XSLT ma znacznie większą objętość, to korzystając z edytora, takiego jak np. Visual Studio, znacznie trudniej o popełnienie błędu w samym dokumencie.&lt;br /&gt;&lt;br /&gt;Inną bardzo dużą zaletą XSLT jest to, że korzystając ze stylów można utworzyć praktycznie dowolny dokument. Sam XSLT jest bardzo potężnym narzędziem, umożliwiającym skomplikowane operacji transformacji danych.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-5989848299623506487?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/t9B2-ctMpaI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/5989848299623506487/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=5989848299623506487" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/5989848299623506487?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/5989848299623506487?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/t9B2-ctMpaI/transformacja-wyniku-zapytania-do.html" title="Transformacja wyniku zapytania do innego formatu" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2008/11/transformacja-wyniku-zapytania-do.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMERHc_cSp7ImA9WxRVFE8.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-8262371651031173988</id><published>2008-11-11T19:00:00.002+01:00</published><updated>2008-11-11T19:16:45.949+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-11T19:16:45.949+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="70-441" /><category scheme="http://www.blogger.com/atom/ns#" term="MCP" /><category scheme="http://www.blogger.com/atom/ns#" term="MCITP" /><title>MCP x 8</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6O7Y2VYrTpwT2LsapM-aIZl7xI4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6O7Y2VYrTpwT2LsapM-aIZl7xI4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6O7Y2VYrTpwT2LsapM-aIZl7xI4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6O7Y2VYrTpwT2LsapM-aIZl7xI4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;No i udało mi się pozytywnie zapoczątkować kolejny rozdział pt. "certyfikacja Microsoftu". Dzisiaj zdałem 70-441 PRO: Designing Database Solutions by Using Microsoft SQL Server 2005. Pierwszy z trzech egzaminów wymaganych do uzyskania tytułu MCITP: Database Developer. Mam nadzieję, że czas będzie mi sprzyjał i do końca roku zamknę całą ścieżkę.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;Tak na marginesie to był już 8 zdany egzamin.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-8262371651031173988?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/F6B-otRr24Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/8262371651031173988/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=8262371651031173988" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/8262371651031173988?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/8262371651031173988?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/F6B-otRr24Y/mcp-x-8.html" title="MCP x 8" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2008/11/mcp-x-8.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIGSXs9eSp7ImA9WxRWEUk.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-7396302483451555201</id><published>2008-10-27T22:37:00.000+01:00</published><updated>2008-10-27T22:38:48.561+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-27T22:38:48.561+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SQL Server 2008" /><category scheme="http://www.blogger.com/atom/ns#" term="SSMS" /><title>SSMS 2008</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/61RgrACWxjyo5C4rUiaw1mNLmsQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/61RgrACWxjyo5C4rUiaw1mNLmsQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/61RgrACWxjyo5C4rUiaw1mNLmsQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/61RgrACWxjyo5C4rUiaw1mNLmsQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;Jak to często bywa podczas udzielania pomocy innym, musiałem wygenerować trochę danych testowych. Jako, że porównywałem dwa rozwiązanie problemu, wykonałem kwerendy generując jednocześnie ich plany wykonania. I tutaj SSMS w wersji 2008 przychodzi z pomocą. W przypadku gdy wykryje brakujące indeksy, podpowiada aby je założyć. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;&lt;br /&gt;Bardzo przyjemny dodatek, który czasami może ułatwić pracę.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-7396302483451555201?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/RYVdYS_q_64" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/7396302483451555201/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=7396302483451555201" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/7396302483451555201?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/7396302483451555201?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/RYVdYS_q_64/ssms-2008.html" title="SSMS 2008" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2008/10/ssms-2008.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUAQ38zeSp7ImA9WxRXE0k.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-1592651603097430913</id><published>2008-10-18T18:23:00.001+02:00</published><updated>2008-10-18T18:27:22.181+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-18T18:27:22.181+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="optymalizacja" /><title>Kolejność robi różnicę</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ulJEuks9EyWvNnUoCsYo4HpBhXM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ulJEuks9EyWvNnUoCsYo4HpBhXM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ulJEuks9EyWvNnUoCsYo4HpBhXM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ulJEuks9EyWvNnUoCsYo4HpBhXM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;Pisząc kwerendy w T-SQL bardzo często decyzja na temat optymalizacji zapytań pozostawiana jest optymalizatorowi. Prawdopodobnie w 9 na 10 przypadków optymalizator wybierze odpowiedni plan wykonania, dzięki któremu zapytanie wykona się w zadowalającym czasie.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;&lt;br /&gt;Tak jest prawdopodobnie w 9 na 10 przypadków. Jednakże od każdej reguły są wyjątki, z którymi optymalizator póki co sobie nie radzi.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;&lt;br /&gt;Jednym z takich wyjątków jest kolejność predykatów. Zademonstruje to na przykładzie.&lt;br /&gt;Na początek utworzę funkcje, która będzie miała zauważalny czas wykonania.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;CREATE FUNCTION dbo.usn_waitfor()&lt;br /&gt;RETURNS INT&lt;br /&gt;AS&lt;br /&gt;BEGIN&lt;br /&gt;DECLARE @i INT&lt;br /&gt;SET @i = 1&lt;br /&gt;WHILE @i &lt; 10000000&lt;br /&gt;     BEGIN&lt;br /&gt;           SET @i = @i + 1&lt;br /&gt;     END&lt;br /&gt;RETURN 1&lt;br /&gt;END&lt;br /&gt;GO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Funkcja ta zwraca wartość 1, jednakże zanim to zrobi inkrementuje 10000000 razy wartość zmiennej @i. Naturalnie funkcja ta mogłaby wykonywać każdą inną czynność, np. odczytywać dane z kilku tabel czy wykonywać operacje arytmetyczne.&lt;br /&gt;&lt;br /&gt;Wykorzystajmy teraz tę funkcję w zapytaniu. Na początek włączę jednakże trochę statystyk.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;SET STATISTICS TIME ON&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;W celu demonstracji potrzebna będzie jeszcze jedna zmienna.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;DECLARE @i INT&lt;br /&gt;SET @i = 1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A teraz bardzo proste zapytanie.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;SELECT 1&lt;br /&gt;WHERE @i = 1 OR dbo.usn_waitfor() = 0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Wykonując to zapytanie wynik otrzymany jest natychmiast. Statystyki w tym przypadku nic nie wykazały.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SQL Server Execution Times:&lt;br /&gt;CPU time = 0 ms,  elapsed time = 0 ms.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Teraz to samo zapytanie, jednakże ze zmienioną kolejnością predykatów. Najpierw będzie sprawdzany wynik funkcji a później wartość zmiennej.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;SELECT 1&lt;br /&gt;WHERE dbo.usn_waitfor() = 0 OR @i = 1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Wynik zwrócony przez to zapytanie jest taki sam jak w poprzednim przypadku, natomiast czas jaki upłynął aby go otrzymać już nie. W moim przypadku na drugie zapytanie serwer potrzebował 18 sekund. Poniżej trochę statystyk.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SQL Server Execution Times:&lt;br /&gt;CPU time = 12657 ms,  elapsed time = 17921 ms.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Skąd więc taka różnica pomiędzy czasami wykonania obu zapytań? Otóż różnica te leży właśnie w kolejności sprawdzania predykatów. Aby nasz warunek był prawdziwy, i zapytanie zwróciło wynik, przynajmniej jeden predykatów musi być prawdziwy. W pierwszym przypadku najpierw sprawdzona została wartość zmiennej, i warunek @i = 1 był prawdziwy. Jako, że przynajmniej jeden z warunków musi być prawdą, drugi z warunków nie musiał być już sprawdzany.&lt;br /&gt;&lt;br /&gt;W przypadku drugiego zapytania to funkcja, która potrzebuje trochę czasu aby została wykonana, brała udział w pierwszym warunku. Dopiero po jej wykonaniu sprawdzany był kolejny warunek, który zwraca prawdę, dzięki czemu otrzymany został wynik zapytania.&lt;br /&gt;&lt;br /&gt;Jak widać warto czasami pomyśleć samemu i nie zdawać się na łaskę optymalizatora. Zmienienie kolejności predykatów może mieć kolosalne znaczenie dla czasu w jakim wykonane zostanie zapytanie.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-1592651603097430913?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/qizG9pHo26w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/1592651603097430913/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=1592651603097430913" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/1592651603097430913?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/1592651603097430913?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/qizG9pHo26w/kolejno-robi-rnic.html" title="Kolejność robi różnicę" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2008/10/kolejno-robi-rnic.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkICSX88eyp7ImA9WxRQGEw.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-4024579546751917329</id><published>2008-10-12T13:07:00.002+02:00</published><updated>2008-10-12T13:22:48.173+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-12T13:22:48.173+02:00</app:edited><title>Beta 71-433</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DWMYcgzCWyJuJSq_HN507fN67Yw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DWMYcgzCWyJuJSq_HN507fN67Yw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DWMYcgzCWyJuJSq_HN507fN67Yw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DWMYcgzCWyJuJSq_HN507fN67Yw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;W mijającym tygodniu miałem okazję zdawać beta egzamin Microsoft® SQL Server® 2008, Database Development. Egzamin ten planowałem zdawać tydzień wcześniej, jednakże centrum egzaminacyjne, które wybrałem podczas rejestracji, skutecznie mi to uniemożliwiło. Ale czego można oczekiwać po firmie, która ma jedno stanowisko, na którym można zdawać egzaminy, a jednocześnie jest partnerem zarówno Prometrica jak i Pearson VUE. Czasami warto by było wziąć pod uwagę zadowolenie klientów, a nie tylko ilość potencjalnych złotówek wpływających na konto.&lt;br /&gt;&lt;br /&gt;Ostatecznie do egzaminu przystępowałem w Wielkiej Brytanii. Jako, że wcześniej miałem już okazję zdawać kilka egzaminów Microsoftu, nic mnie nie zaskoczyło na 71-433. Jedyne czego żałuje to to, że nie spędziłem więcej czasu z SQL Server 2008. Dla mnie ten egzamin był bardziej rozgrzewką przed planowanymi 3 egzaminami z SQL Server 2005, a niżeli chęcią zdobycia nowych kwalifikacji. Mimo wszystko myślę, że było warto i także Microsoft będzie zadowolony z moich komentarzy do pytań. Teraz pozostaje tylko czekać kolejne 8 tygodni na wyniki.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-4024579546751917329?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/k1UqGyMdtxQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/4024579546751917329/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=4024579546751917329" title="Komentarze (1)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/4024579546751917329?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/4024579546751917329?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/k1UqGyMdtxQ/beta-71-433.html" title="Beta 71-433" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2008/10/beta-71-433.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEARn09eCp7ImA9WxRRE0o.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-8211092202352964205</id><published>2008-09-25T21:18:00.003+02:00</published><updated>2008-09-25T21:24:07.360+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-25T21:24:07.360+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Pivot" /><category scheme="http://www.blogger.com/atom/ns#" term="T-SQL" /><category scheme="http://www.blogger.com/atom/ns#" term="Dynamiczny SQL" /><title>Dynamiczne obracanie danych</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DxCO495w1rMOKMGc0mgV8ZSP5y8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DxCO495w1rMOKMGc0mgV8ZSP5y8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DxCO495w1rMOKMGc0mgV8ZSP5y8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DxCO495w1rMOKMGc0mgV8ZSP5y8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;Początkowo miałem pisać dalej o optymalizacji w wykorzystaniem indeksów. Kontynuacja tematu rozpoczętego wcześniej. Dość długo się do tego zabierałem, a w między czasie pojawił się ciekawy problem na forum na stronie wss.pl.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;Zanim jednak przejdę do meritum sprawy, naświetlę trochę temat, wykorzystując banalny przykład obracania danych w SQL 2005/2008 (PIVOT) oraz technikę która umożliwa osiągnięcie tego samego celu w poprzedniej wersji SQL Servera.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;Na początek trochę danych.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;USE TEMPDB&lt;br /&gt;GO&lt;br /&gt;IF OBJECT_ID('tempdb..#T1') IS NOT NULL&lt;br /&gt;DROP TABLE #T1&lt;br /&gt;&lt;br /&gt;CREATE TABLE #T1 (&lt;br /&gt;                CLUB NVARCHAR(40) NOT NULL,&lt;br /&gt;                ATTRIBUTE NVARCHAR(40) NOT NULL,&lt;br /&gt;                VALUE INT&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;ALTER TABLE #T1 WITH NOCHECK&lt;br /&gt;ADD CONSTRAINT PK PRIMARY KEY CLUSTERED(CLUB, ATTRIBUTE)&lt;br /&gt;&lt;br /&gt;INSERT INTO #T1&lt;br /&gt;SELECT 'Diving Experience', '# members', 123 UNION ALL&lt;br /&gt;SELECT 'Diving Experience', '# branches', 8 UNION ALL&lt;br /&gt;SELECT 'Diving Experience', '# equipment', 100  UNION ALL&lt;br /&gt;SELECT 'Global Diving', '# members', 125 UNION ALL&lt;br /&gt;SELECT 'Global Diving', '# branches', 9 UNION ALL&lt;br /&gt;SELECT 'My Scuba', '# members', 127 UNION ALL&lt;br /&gt;SELECT 'My Scuba', '# equipment', 128 UNION ALL&lt;br /&gt;SELECT 'Sharks Diving', '# members', 50 UNION ALL&lt;br /&gt;SELECT 'Sharks Diving', '# equipment', 50 UNION ALL&lt;br /&gt;SELECT 'Sharks Diving', '# branches', 2 UNION ALL&lt;br /&gt;SELECT 'Sharks Diving', '# boats', 1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Tabela #T1 zawiera dane w następującej formie:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;CLUB              ATTRIBUTE   VALUE&lt;br /&gt;----------------- ----------- -----------&lt;br /&gt;Diving Experience # branches  8&lt;br /&gt;Diving Experience # equipment 100&lt;br /&gt;Diving Experience # members   123&lt;br /&gt;Global Diving     # branches  9&lt;br /&gt;Global Diving     # members   125&lt;br /&gt;My Scuba          # equipment 128&lt;br /&gt;My Scuba          # members   127&lt;br /&gt;Sharks Diving     # boats     1&lt;br /&gt;Sharks Diving     # branches  2&lt;br /&gt;Sharks Diving     # equipment 50&lt;br /&gt;Sharks Diving     # members   50&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Naszym celem jest przekształcenia tak danych aby każdy z atrybutów był osobą kolumną. Aby osiągnąć zamierzony cel musimy obrócić dane wokół osi, którą będzie kolumna atrybut.&lt;br /&gt;&lt;br /&gt;Od SQL Servera w wersji 2005 mamy do dyspozycji klauzulę PIVOT.&lt;br /&gt;&lt;br /&gt;Jako kolumny w zapytaniu, podajemy klub dla którego chcemy otrzymać nasze dane, oraz wszystkie dostępne wartości parametrów, a raczej te które nas interesują. Te same wartości parametrów muszą także występować w dalszej części zapytania.&lt;br /&gt;&lt;br /&gt;PIVOT wykorzystuje także funkcję agregującą. W tym poniższym przykładzie będzie to MAX.&lt;br /&gt;&lt;br /&gt;Wykonując zapytanie:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;SELECT&lt;br /&gt;CLUB,&lt;br /&gt;ISNULL([# MEMBERS], 0) AS MEMBERS,&lt;br /&gt;ISNULL([# BRANCHES], 0) AS BRANCHES,&lt;br /&gt;ISNULL([# EQUIPMENT], 0) AS EQUIPMENT,&lt;br /&gt;ISNULL([# BOATS], 0) AS BOATS&lt;br /&gt;FROM #T1&lt;br /&gt;PIVOT (MAX(VALUE) FOR ATTRIBUTE IN ([# MEMBERS], [# BRANCHES], [# EQUIPMENT], [# BOATS])) AS P&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Otrzymamy następujący wynik:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;CLUB              MEMBERS     BRANCHES    EQUIPMENT   BOATS&lt;br /&gt;----------------- ----------- ----------- ----------- -----&lt;br /&gt;Diving Experience 123         8           100         0&lt;br /&gt;Global Diving     125         9           0           0&lt;br /&gt;My Scuba          127         0           128         0&lt;br /&gt;Sharks Diving     50          2           50          1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Każdy z atrybutów stał się teraz osobą kolumną. Teraz w razie potrzeby dane mogą być dalej przetwarzane. Wykorzystanie tabeli w postaci otwartego schematu, gdzie mamy atrybuty i ich wartości w jednym wierszu jest bardzo przydatne w przypadku gdy często zmienia się schemat danych, lub gdy też różne obiekty mają różne wartości parametrów. W SQL Server 2005/2008 ten sam cel można osiągnąć poprzez przechowywanie atrybutów obiektu w postaci XML. Jednakże to temat na inną dyskusję.&lt;br /&gt;&lt;br /&gt;W SQL Server 2000 nie mamy do dyspozycji klauzuli PIVOT, jednakże osiągnięcie tego samego celu nie jest bardzo skomplikowane.&lt;br /&gt;&lt;br /&gt;Poniższe zapytanie zwróci nam ten sam zbiór wyników&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;SELECT&lt;br /&gt;CLUB,&lt;br /&gt;ISNULL(MAX(CASE WHEN ATTRIBUTE = '# MEMBERS' THEN VALUE END),0) AS MEMBERS,&lt;br /&gt;ISNULL(MAX(CASE WHEN ATTRIBUTE = '# BRANCHES' THEN VALUE END),0) AS BRANCHES,&lt;br /&gt;ISNULL(MAX(CASE WHEN ATTRIBUTE = '# EQUIPMENT' THEN VALUE END),0) AS EQUIPMENT,&lt;br /&gt;ISNULL(MAX(CASE WHEN ATTRIBUTE = '# BOATS' THEN VALUE END),0) AS BOATS&lt;br /&gt;FROM #T1&lt;br /&gt;GROUP BY CLUB&lt;br /&gt;ORDER BY CLUB&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Warto zwrócić tutaj uwagę na fakt, że w przypadku PIVOT grupowanie elementów jest ukryte. Jeżeli spojrzymy co robi optymalizator to zauważymy, że plan wykonania w obu przypadkach jest jednakowy. Co więcej zapytanie kompatybilne z SQL Server 2000 ma nieznacznie mniejszy koszt.&lt;br /&gt;&lt;br /&gt;Może trochę nudnawe i przydługie te wprowadzenie do tematu, ale myślę, że warto.&lt;br /&gt;&lt;br /&gt;Przejdźmy więc do meritum problemu. Jeden z użytkowników forum zapytał jak przekształcić dane z następującej postaci:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;a 123&lt;br /&gt;a 124&lt;br /&gt;a 64&lt;br /&gt;b 125&lt;br /&gt;b 126&lt;br /&gt;c 127&lt;br /&gt;c 128&lt;br /&gt;d 129&lt;br /&gt;d 130&lt;br /&gt;d 131&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;do&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;a 123 124 64&lt;br /&gt;b 125 126&lt;br /&gt;c 127 128&lt;br /&gt;d 129 130 131&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Na pierwszy rzut oka mogłoby to wyglądać na prosty przykład obracania danych. Jednakże na samym początku pojawią się pierwszy problem. Która kolumna będzie naszą osią. Pierwsza kolumna to unikalne elementy a druga to jakieś wartości. Brak w tym wszystkim jednej kolumny umożliwiającej nam obrócenie danych.&lt;br /&gt;&lt;br /&gt;Dugi problem to ilość kolumn w wyniku. Z powyższego przykładu danych nie można wywnioskować ilości docelowych kolumn. Jedną z wad PIVOT jest to, że z góry musimy znać wszystkie możliwe kolumny. PIVOT nie pozwala nam tworzyć ich dynamicznie.&lt;br /&gt;&lt;br /&gt;Na początek utwórzmy zbiór danych.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;USE TEMPDB&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;IF OBJECT_ID('tempdb..#T1') IS NOT NULL&lt;br /&gt;DROP TABLE #T1&lt;br /&gt;&lt;br /&gt;CREATE TABLE #T1 (&lt;br /&gt;                ID CHAR(1),&lt;br /&gt;                VAL INT&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;INSERT INTO #T1&lt;br /&gt;SELECT 'a', 123 UNION ALL&lt;br /&gt;SELECT 'a', 124 UNION ALL&lt;br /&gt;SELECT 'a', 64  UNION ALL&lt;br /&gt;SELECT 'b', 125 UNION ALL&lt;br /&gt;SELECT 'b', 126 UNION ALL&lt;br /&gt;SELECT 'c', 127 UNION ALL&lt;br /&gt;SELECT 'c', 128 UNION ALL&lt;br /&gt;SELECT 'd', 129 UNION ALL&lt;br /&gt;SELECT 'd', 130 UNION ALL&lt;br /&gt;SELECT 'd', 131&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Na początek musimy rozwiązać problem kolumny, wokół której będziemy obracać nasze dane.&lt;br /&gt;&lt;br /&gt;W tym celu z pomocą przychodzi nowa w SQL 2005 funkcja ROW_NUMBER.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;IF OBJECT_ID('tempdb..#T2') IS NOT NULL&lt;br /&gt;                DROP TABLE #T2&lt;br /&gt;&lt;br /&gt;;WITH CTE AS (&lt;br /&gt;      SELECT&lt;br /&gt;      ID,&lt;br /&gt;      VAL,&lt;br /&gt;      ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) AS RN,&lt;br /&gt;      'ATTR' + CONVERT(VARCHAR(2),ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID)) AS ATTR&lt;br /&gt;      FROM #T1&lt;br /&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Partycjonujemy nasze dane, dzięki czemu uzyskujemy maksymalną liczbę różnych parametrów. Tworzymy też dodatkową kolumnę, ATTR, która będzie naszą osią. Unikalne parametry tworzymy korzystając ponownie z ROW_NUMBER, tym razem doklejając uzyskaną wartość do attr.&lt;br /&gt;&lt;br /&gt;Tak zmodyfikowane dane wstawiamy do tabeli tymczasowej.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;SELECT * INTO #T2 FROM CTE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Zawartość naszej tabeli przedstawia się w następujący sposób.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;ID  VAL  RN  ATTR&lt;br /&gt;--- ---- --- ------&lt;br /&gt;a   123  1   ATTR1&lt;br /&gt;a   124  2   ATTR2&lt;br /&gt;a   64   3   ATTR3&lt;br /&gt;b   125  1   ATTR1&lt;br /&gt;b   126  2   ATTR2&lt;br /&gt;c   127  1   ATTR1&lt;br /&gt;c   128  2   ATTR2&lt;br /&gt;d   129  1   ATTR1&lt;br /&gt;d   130  2   ATTR2&lt;br /&gt;d   131  3   ATTR3&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Mając teraz kolumnę ATTR możemy przejść do obracania danych. Od razu napotykamy na nasz drugi problem. Ile tak naprawdę będziemy mieli różnych rodzajów atrybutów? W powyższym przykładzie jest to 3 ale może równie dobrze być ich znacznie więcej. Tak więc zwykły PIVOT nam tutaj na niewiele się zda. Musimy wykonać go dynamicznie, a raczej skonstruować zapytanie dynamicznie.&lt;br /&gt;&lt;br /&gt;Na początek musimy zdobyć maksymalną ilość atrybutów.&lt;br /&gt;&lt;br /&gt;W tym celu deklarujemy zmienną i pobieramy maksymalną wartość z kolumny RN&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;DECLARE @MAXATTR AS INT&lt;br /&gt;SELECT @MAXATTR = MAX(RN) FROM #T2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Deklarujemy także kolejnych kilka zmiennych, które będą wykorzystane przy tworzeniu dynamicznego zapytania.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;DECLARE @I AS int&lt;br /&gt;DECLARE @SQL AS NVARCHAR(200)&lt;br /&gt;DECLARE @PIVOTSQL AS NVARCHAR(200)&lt;br /&gt;DECLARE @TABLESQL AS NVARCHAR(400)&lt;br /&gt;DECLARE @FINALSQL AS NVARCHAR(400)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Mając to wszystko możemy wygenerować nasz dynamiczny kod.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;WHILE @I &lt;= @MAXATTR&lt;br /&gt;BEGIN&lt;br /&gt;&lt;br /&gt;SET @SQL = @SQL + ', attr' + CONVERT(NVARCHAR(4),@I)&lt;br /&gt;SET @PIVOTSQL = @PIVOTSQL + '[ATTR' + CONVERT(NVARCHAR(2),@I) + '],'&lt;br /&gt;SET @TABLESQL = @TABLESQL + 'ALTER TABLE #T3 ADD ATTR' + CONVERT(NVARCHAR(4),@I) + ' INT '&lt;br /&gt;SET @FINALSQL = @FINALSQL + ', MAX(ISNULL(ATTR' + CONVERT(NVARCHAR(4),@I) + ',0)) AS COLUMN' + CONVERT(NVARCHAR(4),@I)&lt;br /&gt;SET @I = @I + 1&lt;br /&gt;&lt;br /&gt;END&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Kilka słów o tym co dzieję się w pętli, która wykonywana jest tyle razy ile mamy unikalnych atrybutów.&lt;br /&gt;&lt;br /&gt;Zmienna SQL przechowuje pierwszą część naszego zapytania, tzn wszystkie kolumny, które będą występowały po SELECT.&lt;br /&gt;&lt;br /&gt;Zmienna PIVOTSQL przechowuje wszystkie wartości atrybutów, które docelowo będą naszymi kolumnami.&lt;br /&gt;&lt;br /&gt;Zmienna TABLESQL, tworzy kod który będzie modyfikował jedną z tabel docelowych. Kilka słów więcej o niej w dalszej części.&lt;br /&gt;&lt;br /&gt;Zmienna FINALSQL przechowuje zapytanie, które zwróci nam ostateczny wynik. Zapytanie utworzone w tej zmiennej grupuje nasze dane.&lt;br /&gt;&lt;br /&gt;W pętli tej jednakże tworzymy tylko fragmenty zapytań, z wyjątkiem TABLESQL, które po zakończeniu pętli jest już kompletne.&lt;br /&gt;&lt;br /&gt;Tworzymy teraz nasze ostateczne zapytania.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;SET @PIVOTSQL = STUFF(@PIVOTSQL,LEN(@PIVOTSQL),1,'')&lt;br /&gt;SET @SQL = @SQL + ' FROM #T2 PIVOT(MAX(VAL) FOR ATTR IN(' + @PIVOTSQL + ')) AS P '&lt;br /&gt;SET @SQL = 'INSERT INTO #T3 SELECT * FROM (' + @SQL + ') AS DSQL'&lt;br /&gt;SET @FINALSQL  = @FINALSQL + ' FROM #T3 GROUP BY ID ORDER BY ID'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Tworzymy także kolejną tabelę tymczasową, która będzie przechowywać wynik obracania danych.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;IF OBJECT_ID('tempdb..#T3') IS NOT NULL&lt;br /&gt;DROP TABLE #T3&lt;br /&gt;&lt;br /&gt;CREATE TABLE #T3 (&lt;br /&gt;   ID CHAR(1)&lt;br /&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Tabela ta na początek posiada tylko jedną kolumnę, która zawiera unikalne elementy. W momencie kiedy ją tworzymy nie wiemy ile będziemy mieli docelowo różnych atrybutów (kolumn). Kolumny te dodamy po uruchomianiu dynamicznie wygenerowanego kodu. W każdej iteracji naszej pętli dodawana była jedna kolumna odpowiadająca wartości naszego atrybutu.&lt;br /&gt;&lt;br /&gt;Teraz wykonujemy nasze dynamicznie utworzone zapytania.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;EXEC SP_EXECUTESQL @TABLESQL&lt;br /&gt;&lt;br /&gt;EXEC SP_EXECUTESQL @SQL&lt;br /&gt;&lt;br /&gt;EXEC SP_EXECUTESQL @FINALSQL&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ostatnie z nich zwraca nam nasz pożądany wynik.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;ID   COLUMN1     COLUMN2     COLUMN3   &lt;br /&gt;---- ----------- ----------- -------&lt;br /&gt;a    123         124         64        &lt;br /&gt;b    125         126         0         &lt;br /&gt;c    127         128         0          &lt;br /&gt;d    129         130         131&lt;/span&gt;       &lt;br /&gt;&lt;br /&gt;Jak widać nie ograniczenie jakie niesie za sobą PIVOT idzie łatwo ominąć generując kod dynamicznie.&lt;br /&gt;&lt;br /&gt;PS. Po napisaniu oryginalnego rozwiązania postanowiłem je jeszcze trochę zoptymalizować. Oryginalny kod wymagał użycia trzech tabel tymczasowych, a jedna z nich miała dynamicznie dodawane kolumny. Wszystko to za sprawą tego, że tabela #T2 poza danymi wynikowymi posiadała także kolumnę RN, która przechowywała maksymalne wartości atrybutów dla każdej z unikalnych grup. W wyniku przekształcania danych dużo wierszy posiadało wartości NULL. Eliminowane one były dopiero w trzeciej tabeli tymczasowej.&lt;br /&gt;&lt;br /&gt;Poniżej cały kod, delikatnie zmodyfikowany. Wynik oczywiście taki sam.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;USE TEMPDB&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;IF OBJECT_ID('tempdb..#T1') IS NOT NULL&lt;br /&gt;DROP TABLE #T1&lt;br /&gt;&lt;br /&gt;CREATE TABLE #T1 (&lt;br /&gt;                ID CHAR(1),&lt;br /&gt;                VAL INT&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;INSERT INTO #T1&lt;br /&gt;SELECT 'a', 123 UNION ALL&lt;br /&gt;SELECT 'a', 124 UNION ALL&lt;br /&gt;SELECT 'a', 64  UNION ALL&lt;br /&gt;SELECT 'b', 125 UNION ALL&lt;br /&gt;SELECT 'b', 126 UNION ALL&lt;br /&gt;SELECT 'c', 127 UNION ALL&lt;br /&gt;SELECT 'c', 128 UNION ALL&lt;br /&gt;SELECT 'd', 129 UNION ALL&lt;br /&gt;SELECT 'd', 130 UNION ALL&lt;br /&gt;SELECT 'd', 131&lt;br /&gt;IF OBJECT_ID('tempdb..#T2') IS NOT NULL&lt;br /&gt;                DROP TABLE #T2&lt;br /&gt;;WITH CTE AS (&lt;br /&gt;                SELECT&lt;br /&gt;                ID,&lt;br /&gt;                VAL,&lt;br /&gt;                'ATTR' + CONVERT(VARCHAR(2),ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID)) AS ATTR&lt;br /&gt;                FROM #T1&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;SELECT * INTO #T2 FROM CTE&lt;br /&gt;&lt;br /&gt;DECLARE @MAXATTR AS INT&lt;br /&gt;SELECT @MAXATTR = MAX(RN) FROM (&lt;br /&gt;                SELECT ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) AS RN&lt;br /&gt;                FROM #T1&lt;br /&gt;) AS MAXATTR&lt;br /&gt;DECLARE @I AS int&lt;br /&gt;DECLARE @SQL AS NVARCHAR(400)&lt;br /&gt;DECLARE @PIVOTSQL AS NVARCHAR(200)&lt;br /&gt;SET @SQL = 'SELECT ID '&lt;br /&gt;SET @PIVOTSQL = ''&lt;br /&gt;SET @I = 1&lt;br /&gt;WHILE @I &lt;= @MAXATTR&lt;br /&gt;BEGIN&lt;br /&gt;SET @SQL = @SQL + ', ISNULL(attr' + CONVERT(NVARCHAR(4),@I) + ', 0) AS COLUMN' + CONVERT(NVARCHAR(4),@I)&lt;br /&gt;SET @PIVOTSQL = @PIVOTSQL + '[ATTR' + CONVERT(NVARCHAR(2),@I) + '],'&lt;br /&gt;SET @I = @I + 1&lt;br /&gt;END&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SET @PIVOTSQL = STUFF(@PIVOTSQL,LEN(@PIVOTSQL),1,'')&lt;br /&gt;SET @SQL = @SQL + ' FROM #T2 PIVOT(MAX(VAL) FOR ATTR IN(' + @PIVOTSQL + ')) AS P '&lt;br /&gt;EXEC SP_EXECUTESQL @SQL&lt;br /&gt;DROP TABLE #T1&lt;br /&gt;DROP TABLE #T2&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-8211092202352964205?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/TShpeHE9A1w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/8211092202352964205/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=8211092202352964205" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/8211092202352964205?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/8211092202352964205?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/TShpeHE9A1w/dynamiczne-obracanie-danych.html" title="Dynamiczne obracanie danych" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2008/09/dynamiczne-obracanie-danych.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkICRn84eip7ImA9WhVTEU8.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-234534157137696769</id><published>2008-09-03T00:28:00.014+02:00</published><updated>2012-02-25T01:09:27.132+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-25T01:09:27.132+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="plany zapytań" /><category scheme="http://www.blogger.com/atom/ns#" term="T-SQL" /><category scheme="http://www.blogger.com/atom/ns#" term="optymalizacja" /><category scheme="http://www.blogger.com/atom/ns#" term="indeksy" /><title>Optymalizacja cz.1 – Indeksy</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/70Ug9I28uwL34yVivym_k1CetMA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/70Ug9I28uwL34yVivym_k1CetMA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/70Ug9I28uwL34yVivym_k1CetMA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/70Ug9I28uwL34yVivym_k1CetMA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;strong&gt;&lt;span style="color: #cc6600;"&gt;Wstęp&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;Pierwszą część dotyczącą optymalizacji baz danych rozpocznę od indeksów. Indeks to uporządkowany zbiór danych. Przykładem indeksu jest książka telefoniczna, która zawiera numery telefonów uporządkowana wg nazwiska czy nazwy firmy.&lt;/span&gt;&lt;span style="font-family: verdana; font-size: 85%;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;Korzystając z odpowiednich indeksów można w znaczący sposób skrócić czas wykonywania zapytania do bazy danych. Nic jednak za darmo. Indeksy mają swój koszt i muszą one być odpowiednio przemyślane. Kosztem indeksu jest miejsce na dysku oraz czas związany z operacjami modyfikacji danych (INSERT, UPDATE, DELETE).&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;Tak jak każda baza danych jest inna tak też nie ma uniwersalnej reguły dotyczącej indeksów. Mając na uwadze fakt, że w przypadku dodania, usunięcia lub modyfikacji danych poza aktualizacją tabeli aktualizowane są także indeksy, byłoby nie rozsądnym dodawanie zbyt wielu indeksów w bazie danych, która jest często aktualizowana. Natomiast w przypadku bazy danych, która jest tylko odczytywana i służy do produkcji raportów większa liczba indeksów niewątpliwie będzie korzystna.&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;strong&gt;&lt;span style="color: #cc6600;"&gt;A jak to wygląda w praktyce...&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;Nie zanudzając teorią przyjdźmy do praktycznego zastosowania. We wszystkich przykładach wykorzystywać będę bazę danych Northwind.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;Aby pokazać korzyści płynące z indeksów, usunąłem z tabel istniejące już wcześniej indeksy.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;W przypadku braku jakiegokolwiek indeksu skanowana musi być cała tabela.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;span style="font-family: verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="font-size: 85%;"&gt;
&lt;span style="font-family: verdana;"&gt;&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;span style="color: #009900; font-family: 'courier new';"&gt;select orderid, customerid, orderdate from orders&lt;br /&gt;where OrderDate &amp;gt; '19970101'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: verdana;"&gt;
&lt;span style="font-family: verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="font-size: 85%;"&gt;
&lt;span style="font-family: verdana;"&gt;&lt;span style="font-family: verdana;"&gt;Powyższe zapytanie generuje następujący plan zapytania&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: verdana;"&gt;&lt;span style="font-family: verdana;"&gt;
&lt;div align="left"&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5241555536926203554" src="http://4.bp.blogspot.com/_Lh9RN7xKDCU/SL2-_Wj33qI/AAAAAAAAABg/YcHeQkGJSJk/s320/1.JPG" style="cursor: hand; display: block; margin: 0px auto 10px; text-align: center;" /&gt;&lt;/span&gt;&lt;span style="font-family: verdana; font-size: x-small;"&gt;Zapytanie to także wymagało 20 logicznych operacji odczytu.&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;
&lt;span style="font-family: verdana; font-size: x-small;"&gt;Utwórzmy więc indeks, który pokryje wszystkie kolumny biorące udział w zapytaniu. W zależności od tego czy baza danych jest na SQL Server 2000 czy na SQL Server 2005 mamy do dyspozycji dwa typy indeksów. W przypadku SQL Server 2000, jeżeli byśmy chcieli utworzyć indeks, który pokryłby wszystkie kolumny biorące udział w zapytaniu, wszystkie te kolumny muszą być kluczami indeksu.&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;
&lt;span style="font-family: verdana; font-size: x-small;"&gt;Poniższy kod utworzy nam pożądany indeks.&lt;/span&gt;&lt;/div&gt;
&lt;div align="left" style="font-size: 85%;"&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;span style="color: #009900; font-family: 'courier new';"&gt;create index idx_ncl_od on orders(orderdate, orderid, customerid)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left" style="font-size: 85%;"&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;Wadą tego indeksu jest to, że w przypadku aktualizacji wszystkie klucze muszą być odpowiednio aktualizowane.&lt;/span&gt;&lt;/div&gt;
&lt;div align="left" style="font-size: 85%;"&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;Znacznie bardziej optymalne rozwiązanie umożliwia nam SQL Server 2005, gdzie kluczem indeksu będzie kolumna, która używana jest jako predykat, natomiast pozostałe kolumny dodamy w klauzuli include. W przypadku modyfikacji danych tylko jedna kolumna będzie powodowała dodatkowy koszt. Naturalnie wielkość indeksu na dysku będzie taka sama w przypadku obu rozwiązań. Poniżej zapytanie, które utworzy nam indeks, który pokryje wszystkie kolumny w zapytaniu.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-size: 85%;"&gt;
&lt;span style="color: #009900; font-family: 'courier new'; font-size: 85%;"&gt;create index idx_ncl_in_od on orders(orderdate) include(orderid, customerid)&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;&lt;div align="left" style="font-size: 85%;"&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;Wywołując ponownie nasze zapytanie otrzymujemy poniższy plan wykonania.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-size: 85%;"&gt;
&lt;a href="http://1.bp.blogspot.com/_Lh9RN7xKDCU/SL2_xmzXpEI/AAAAAAAAABo/ANLR7u7MIbc/s1600-h/2.JPG"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5241556400279626818" src="http://1.bp.blogspot.com/_Lh9RN7xKDCU/SL2_xmzXpEI/AAAAAAAAABo/ANLR7u7MIbc/s320/2.JPG" style="cursor: hand;" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;Jak widać w tym przypadku nie skanowaliśmy już całej tabeli, a tylko część indeksu. &lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;br /&gt;&lt;div align="left"&gt;
W przypadku pierwszego zapytania bez indeksu koniecznych było 20 logicznych operacji odczytu. W drugim przypadku było ich tylko 5.&lt;/div&gt;
&lt;div align="left"&gt;
Z uwagi na fakt, że indeks ten nie będzie już nam potrzebny w kolejnych przykładach zostanie on teraz usunięty.&lt;/div&gt;
&lt;div align="left"&gt;
&lt;span style="color: #009900; font-family: 'courier new';"&gt;drop index idx_ncl_in_od on orders.&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;
Dotychczas korzystaliśmy tylko z indeksu nieklastrowego. Indeks nieklastrowy charakteryzuje się tym, że posiada on dane tylko z tych kolumn, które są jego kluczami lub kolumn dołączonych za pomocą instrukcji include.&lt;/div&gt;
&lt;div align="left"&gt;
Kolejnym indeksem jaki założymy na naszej tabeli będzie indeks klastrowy. Indeks klastrowy poza danymi pochodzącymi z kolumny, która jest kluczem posiada wszystkie pozostałe dane z tabeli. Indeks klastrowy to tak na prawdę dane. Dane w takim indeksie będą posortowane wg. kolumny klucza.&lt;/div&gt;
&lt;div align="left"&gt;
Poniższe zapytanie utworzy nam indeks klastrowy oraz klucz podstawowy na kolumnie OrderID.&lt;/div&gt;
&lt;div align="left"&gt;
&lt;span style="color: #009900; font-family: 'courier new';"&gt;ALTER TABLE dbo.Orders ADD CONSTRAINT&lt;br /&gt;PK_Orders PRIMARY KEY CLUSTERED (OrderID)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;
Wykonując ponownie nasze zapytanie otrzymamy poniższy plan wykonania.&lt;/div&gt;
&lt;div&gt;
&lt;a href="http://2.bp.blogspot.com/_Lh9RN7xKDCU/SL3APFS6aEI/AAAAAAAAABw/XhSxZgWJzi0/s1600-h/3.JPG"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5241556906681198658" src="http://2.bp.blogspot.com/_Lh9RN7xKDCU/SL3APFS6aEI/AAAAAAAAABw/XhSxZgWJzi0/s320/3.JPG" style="cursor: hand;" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
Jak widać w tym przypadku nie skanujemy już zawartości tabeli a indeks klastrowy, który zawiera wszystkie dane posortowane wg. kolumny OrderID. Przed założeniem tego typu indeksu należy się poważnie zastanowić, która z kolumn będzie jego kluczem. W tabeli możemy mieć tylko jeden indeks klastrowy. SQL Server pozwala nam ponadto utworzyć 249 indeksów nieklastrowych.&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
W przypadku gdy założymy na tabeli także indeks nieklastrowy, nieunikalny, klucz indeksu klastrowego będzie dodatkowym kluczem indeksu nieklastrowego. Niezależnie od tego czy czy indeks nieklastrowy jest unikalny czy nie, kolumna klucza klastrowego będzie także częścią tego indeksu. Ma to związek z faktem z tym, że w przypadku kiedy w tabeli znajduje się indeks klastrowy indeks nieklastrowy posiada do niego wskaźnik. W przypadku braku indeksu klastrowego indeks nieklastrowy zawiera wskaźnik do wiersza i pliku gdzie znajdują się dane.&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
Aby to zademonstrować założę teraz na tabeli indeks nieklastrowy, którego kluczem będzie kolumna OrderDate.&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
&lt;span style="color: #009900; font-family: 'courier new';"&gt;CREATE INDEX OrderDate ON Orders(OrderDate)&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
Wykonajmy teraz poniższe zapytanie i przeanalizujmy plan wykonania.&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
&lt;span style="color: #009900;"&gt;select orderid, orderdate from orders&lt;br /&gt;where OrderDate &amp;gt; '19970101'&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
&lt;a href="http://3.bp.blogspot.com/_Lh9RN7xKDCU/SL3AmwgA77I/AAAAAAAAAB4/RaX-oltO1qQ/s1600-h/4.JPG"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5241557313415868338" src="http://3.bp.blogspot.com/_Lh9RN7xKDCU/SL3AmwgA77I/AAAAAAAAAB4/RaX-oltO1qQ/s320/4.JPG" style="cursor: hand;" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
Mimo tego, że zakładając indeks nieklastrowy, jako klucz podaliśmy tylko kolumnę OrderDate nasze zapytanie nie wymagało skanowania całej tabeli, a raczej indeksu klastrowego. Zamiast tego wykonany został częściowy skan tabeli poprzedzony odnalezieniem pierwszego wiersza spełniającego predykat.&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
Dotychczasowe zapytania wykorzystywały tylko jeden z indeksów, choć tak na prawdę w ostatnim przypadku gdybyśmy nie mieli indeksu klastrowego optymalizator wybrałby skan całej tabeli, lub w przypadku wysokiej selektywności zapytania częściowy skan indeksu nieklastrowego w połączeniu z przeszukaniem wszystkich wskaźników do wierszy i plików zawierających dane.&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
W ten sposób doszedłem do selektywności zapytań. Czym więc jest selektywność zapytań i jak ona wpływa na wydajność? Selektywność jest to iloraz oczekiwanej liczby wierszy do wszystkich jakie znajdują się w tabeli.&amp;nbsp;&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
Wysoka selektywność oznacza relatywnie małą ilość wyników, natomiast niska selektywność dużą ilość wierszy w wyniku zapytania.&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
Poniższe zapytanie cechuje się wysoką selektywnością.&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
&lt;span style="color: #009900; font-family: 'courier new';"&gt;select orderid, customerid from orders&lt;br /&gt;where OrderDate &amp;gt; '19980505'&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
Rezultatem tego zapytania będą tylko 4 wiersze, co stanowi 0,48% wszystkich wierszy w tabeli.&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
Przyjrzyjmy się teraz planowi wykonania.&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
&lt;a href="http://3.bp.blogspot.com/_Lh9RN7xKDCU/SL3A-mwplUI/AAAAAAAAACA/CizxezhgeGk/s1600-h/5.JPG"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5241557723118146882" src="http://3.bp.blogspot.com/_Lh9RN7xKDCU/SL3A-mwplUI/AAAAAAAAACA/CizxezhgeGk/s320/5.JPG" style="cursor: hand;" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
Z uwagi na fakt, że nasz indeks nieklastrowy nie pokrywa wszystkich kolumn zapytania optymalizator zdecydował, najpierw o wyszukaniu rekordów spełniających nasz predykat, a później dla każdego ze znalezionych wierszy wykonał przeszukanie indeksu klastrowego w celu pobrania danych z kolumny CustomerID. Wyszukanie danych z kolumny CustomerID jest bardzo kosztowną operacją. Dla każdego ze znalezionych wierszy przeprowadzony musi być skan indeksu. Statystycznie indeks skanowany jest w 50%.&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
Zmienimy teraz nieznacznie zakres danych&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
&lt;span style="color: #009900; font-family: 'courier new';"&gt;select orderid, customerid from orders&lt;br /&gt;where OrderDate &amp;gt; '19980504'&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
W wyniku tego zapytania otrzymamy 8 wierszy co stanowi 0,96% wszystkich wierszy w tabeli. Przyjrzyjmy się ponownie planowi wykonania zapytania.&lt;/div&gt;
&lt;div&gt;
&lt;a href="http://3.bp.blogspot.com/_Lh9RN7xKDCU/SL3BQNt_sbI/AAAAAAAAACI/86bQQ06JveU/s1600-h/6.JPG"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5241558025633771954" src="http://3.bp.blogspot.com/_Lh9RN7xKDCU/SL3BQNt_sbI/AAAAAAAAACI/86bQQ06JveU/s320/6.JPG" style="cursor: hand;" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
Jak wspomniałem wcześniej przeszukanie całego indeksu klastrowego, lub też tabeli w przypadku jego braku, dla każdego wiersza jest bardzo kosztowną operacją. Dlatego też optymalizator zdecydował, że bardziej korzystne będzie zeskanowanie tylko raz całego indeksu klastrowego.&lt;br /&gt;
Na dowód tego wykonam kolejne zapytanie, które wykorzysta indeks nieklastrowy.&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
&lt;span style="color: #009900; font-family: 'courier new';"&gt;select orderid, customerid from orders with (index = 3)&lt;br /&gt;where OrderDate &amp;gt; '19980504'&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
W wyniku tego zapytania otrzymamy poniższy, znajomy już nam plan.&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
&lt;a href="http://2.bp.blogspot.com/_Lh9RN7xKDCU/SL3BoKtakVI/AAAAAAAAACQ/C4DAX7O_AFo/s1600-h/7.JPG"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5241558437142892882" src="http://2.bp.blogspot.com/_Lh9RN7xKDCU/SL3BoKtakVI/AAAAAAAAACQ/C4DAX7O_AFo/s320/7.JPG" style="cursor: hand;" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
W moim przypadku koszt tego zapytania to 0,023443, podczas gdy poprzedniego, w którym optymalizator sam wybrał najlepsze rozwiązanie to 0,0182691.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span style="color: #cc6600;"&gt;Zakończenie&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
Indeksy mogą w znacznym stopniu zoptymalizować zapytania do bazy danych. W powyższych zapytaniach nie było może to tak bardzo widoczne, gdyż głównie koncentrowałem się na tym by przedstawić jak działają indeksy i jak optymalizator je wykorzystuje. Temat indeksów poruszę ponownie w przyszłości, wtedy też o wiele bardziej widoczne będą korzyści z nich płynące a także koszt, czego w tym artykule nie poruszyłem.&lt;/div&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-234534157137696769?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/o65sjLSurN8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/234534157137696769/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=234534157137696769" title="Komentarze (1)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/234534157137696769?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/234534157137696769?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/o65sjLSurN8/optymalizacja-cz1-indeksy.html" title="Optymalizacja cz.1 – Indeksy" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_Lh9RN7xKDCU/SL2-_Wj33qI/AAAAAAAAABg/YcHeQkGJSJk/s72-c/1.JPG" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2008/09/optymalizacja-cz1-indeksy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04NRngzcSp7ImA9WhVTEU8.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-7175309671366192987</id><published>2008-08-04T08:59:00.005+02:00</published><updated>2012-02-25T00:26:37.689+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-25T00:26:37.689+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="cte" /><category scheme="http://www.blogger.com/atom/ns#" term="T-SQL" /><category scheme="http://www.blogger.com/atom/ns#" term="row_number" /><category scheme="http://www.blogger.com/atom/ns#" term="duplikaty" /><title>Usuwanie duplikatów</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/qFdIy42qHIzA5rXo1ds6sBgEtr8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qFdIy42qHIzA5rXo1ds6sBgEtr8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/qFdIy42qHIzA5rXo1ds6sBgEtr8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qFdIy42qHIzA5rXo1ds6sBgEtr8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-family: verdana; font-size: 85%;"&gt;Czasami zdarza się tak, że w naszej bazie dancyh występują duplikaty. Nie powinno się to zdarzyc jeżeli są dobre klucze podstawowe w tabelach. Jedkaże kiedy ich nie mamy, lub kiedy dane są importowane z pliku płaskiego, który nie ma żadnej kontroli poprawności danych, musimy sie pozbyć tych nadmiernych informacji.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;br /&gt;Istnieje kilka sposobów na usuwanie duplikatów. W zależności od tego czy uważamy za duplikat wiersz, który ma wszystkie wartości w kolumnach takie same jak inny wiersz w tabeli czy duplikatem będzie dla nas wiersz którego jedna kolumna ma taką samą wartość w innym wierszu, trzeba rozważyć różne techiniki usuwania nadmiernych danych.&lt;br /&gt;&lt;br /&gt;Na początek stworzę przykładową tabelę, którą wypełnię danymi.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #009900; font-family: 'courier new';"&gt;USE TEMPDB&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;IF OBJECT_ID('tempdb..#KLIENCI') IS NOT NULL&lt;br /&gt;DROP TABLE #KLIENCI&lt;br /&gt;&lt;br /&gt;CREATE TABLE #KLIENCI (&lt;br /&gt;ID INT,&lt;br /&gt;NAZWA VARCHAR(50),&lt;br /&gt;TELEFON VARCHAR(9)&lt;br /&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #009900; font-family: 'courier new';"&gt;INSERT INTO #KLIENCI (ID, NAZWA, TELEFON)&lt;br /&gt;SELECT '1', 'CONTOSO LTD', '123456789'&lt;br /&gt;UNION ALL&lt;br /&gt;SELECT '2', 'MERCURY LTD', '987456321'&lt;br /&gt;UNION ALL&lt;br /&gt;SELECT '3', 'NOWY SWIAT', '564789321'&lt;br /&gt;UNION ALL&lt;br /&gt;SELECT '1', 'CONTOSO LTD', '123456789'&lt;br /&gt;UNION ALL&lt;br /&gt;SELECT '2', 'MERCURY LTD', '111111111'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pobierzmy teraz zawartość tabeli.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #009900; font-family: 'courier new';"&gt;SELECT * FROM #KLIENCI&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #009900; font-family: 'courier new';"&gt;ID NAZWA TELEFON&lt;br /&gt;-------- ------------ ---------&lt;br /&gt;1 CONTOSO LTD 123456789&lt;br /&gt;2 MERCURY LTD 987456321&lt;br /&gt;3 NOWY SWIAT 564789321&lt;br /&gt;1 CONTOSO LTD 123456789&lt;br /&gt;2 MERCURY LTD 111111111&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Jak widać z powyższego listingu mamy dwa rodzaje duplikatów. Pierwszy dla klienta Contoso Ltd ma wszystkie wartości w kolumnach w obu wierszah identyczne. Drugi typ to klient Mercury Ltd (id = 2), który ma dwie różne wartości w kolumnie telefon.&lt;br /&gt;&lt;br /&gt;Pierwszy typ duplikatów możemy usunąć korzystając z tabeli tymczasowej, którą wypełniamy unikalnymi wierszami. Następnie usuwamy wszystkie dane z naszej orginalnej tabeli a później kopiujemy zawartość tabeli tymczasowej do naszej tabeli pierwotnej.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #009900; font-family: 'courier new';"&gt;SELECT DISTINCT * INTO #DUPLIKATY FROM #KLIENCI&lt;br /&gt;&lt;br /&gt;TRUNCATE TABLE #KLIENCI&lt;br /&gt;&lt;br /&gt;INSERT INTO #KLIENCI(ID, NAZWA, TELEFON) SELECT ID, NAZWA, TELEFON FROM #DUPLIKATY&lt;br /&gt;DROP TABLE #DUPLIKATY&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pobierając zawartość naszej tabeli otrzymamy teraz następujący rezultat:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #009900; font-family: 'courier new';"&gt;ID NAZWA TELEFON&lt;br /&gt;----------- ------------ ---------&lt;br /&gt;1 CONTOSO LTD 123456789&lt;br /&gt;2 MERCURY LTD 111111111&lt;br /&gt;2 MERCURY LTD 987456321&lt;br /&gt;3 NOWY SWIAT 564789321&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Jak widać pozbyliśmy się jednego wiersza dla klienta Contoso Ltd. Technika ta będzie działać zarówno na SQL Server 2000 jak i nowszych wersjach.&lt;br /&gt;&lt;br /&gt;Znacznie bardziej efektywną metodą i pozwalającą nam usuwać duplikaty, gdzie tylko kilka kolumn ma takie same wartości dla różnych wierszy jest technika z wykorzystaniem nowej funkcji, dostępnej od SQL Server 2005, ROW_NUMBER oraz CTE.&lt;br /&gt;&lt;br /&gt;Korzystając z funkcji ROW_NUMBER tworzymy numery kolejnych wierszy, jednocześnie partycjonując nasze wyniki. W naszym przypadku uznajemy za duplikat wiersz który ma taką samą wartość identyfikatora klienta w dwóch lub więcej wierszach. Skorzystamy więc z funkcji ROW_NUMBER oraz bedziemy partycjonować nasze wyniki w oparciu o kolumnę id.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #009900; font-family: 'courier new';"&gt;WITH DUPLIKATY AS (&lt;br /&gt;SELECT ID, NAZWA, TELEFON, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) AS RN FROM #KLIENCI&lt;br /&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Jeżeli byśmy wyświetlili zawartość naszego CTE, otrzymalibyśmy następujące rezultaty&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #009900; font-family: 'courier new';"&gt;ID NAZWA TELEFON RN&lt;br /&gt;----------- ------------ --------- --&lt;br /&gt;1 CONTOSO LTD 123456789 1&lt;br /&gt;2 MERCURY LTD 111111111 1&lt;br /&gt;2 MERCURY LTD 987456321 2&lt;br /&gt;3 NOWY SWIAT 564789321 1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Teraz jedyne co musimy zrobić to usunąć nadmiarowe wiersze.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #009900; font-family: 'courier new';"&gt;DELETE DUPLIKATY WHERE RN &amp;gt; 1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pobieramy zawartość naszej tabeli&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #009900; font-family: 'courier new';"&gt;SELECT * FROM #KLIENCI&lt;br /&gt;&lt;br /&gt;ID NAZWA TELEFON&lt;br /&gt;----------- ------------ ---------&lt;br /&gt;1 CONTOSO LTD 123456789&lt;br /&gt;2 MERCURY LTD 111111111&lt;br /&gt;3 NOWY SWIAT 564789321&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Teraz mając usunięte duplikaty, możemy założyć klucz podstawowy w naszej tabeli.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-7175309671366192987?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/Jyy73DMO8sQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/7175309671366192987/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=7175309671366192987" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/7175309671366192987?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/7175309671366192987?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/Jyy73DMO8sQ/uswanie-duplikatw.html" title="Usuwanie duplikatów" /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2008/08/uswanie-duplikatw.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YNR3k6eyp7ImA9WxRTF0U.&quot;"><id>tag:blogger.com,1999:blog-5256701949692196546.post-609404526318042361</id><published>2008-08-03T10:29:00.004+02:00</published><updated>2008-09-07T11:53:16.713+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-07T11:53:16.713+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sql" /><category scheme="http://www.blogger.com/atom/ns#" term="import xml" /><category scheme="http://www.blogger.com/atom/ns#" term="xml" /><category scheme="http://www.blogger.com/atom/ns#" term="T-SQL" /><category scheme="http://www.blogger.com/atom/ns#" term="stored procedure" /><category scheme="http://www.blogger.com/atom/ns#" term="sqlxml" /><title>Importowanie danych z XML do bazy danych.</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9hAOVBsJjnL1Qe2K2eetoVXmy8M/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9hAOVBsJjnL1Qe2K2eetoVXmy8M/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9hAOVBsJjnL1Qe2K2eetoVXmy8M/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9hAOVBsJjnL1Qe2K2eetoVXmy8M/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;&lt;strong&gt;Wstęp&lt;br /&gt;&lt;/strong&gt;Aplikacje biznesowe coraz częściej wykorzystują dane pochodzących z róznych źródeł. Coraz częsniej dane te dostarczane są w formacie XML. SQL Server 2005 oferuje wiele funkcji, które umożliwiają przetwarzanie danych w formacie XML.&lt;br /&gt;SQL Server 2005 potrafi przechowywać dane jako dokumenty XML, lub też przetwarzać je i przechowywac zachowując model relacyjnej bazy danych.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;&lt;strong&gt;Praktyczne zastosowanie&lt;/strong&gt;&lt;br /&gt;Nie zanudzając dalej teorią pora przejść do konkretnego zastowanie XML w powiązaniu z SQL Server 2005. Poniższy przykład pokaże z jaką łatwością dane mogą zostać zaimportowane z pliku, lub łancucha znaków w formacie XML do tabeli bazy danych.&lt;br /&gt;Poniższy przykład jako dokument XMl będzie wykorzystywał tabelę kursów walut publikowaną na stronach Narodowego Banku Polskiego.&lt;br /&gt;Fragment dokumentu XML, z którego będę korzystał w dalszej częsci tego artykułu:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;&amp;lt;tabela_kursow typ="A"&amp;gt;&lt;br /&gt;&amp;lt;numer_tabeli&amp;gt;150/A/NBP/2008&amp;lt;/numer_tabeli&amp;gt;&lt;br /&gt;&amp;lt;data_publikacji&amp;gt;2008-08-01&amp;lt;/data_publikacji&amp;gt;&lt;br /&gt;&amp;lt;pozycja&amp;gt;&lt;br /&gt;&amp;lt;nazwa_waluty&amp;gt;dolar australijski&amp;lt;/nazwa_waluty&amp;gt;&lt;br /&gt;&amp;lt;przelicznik&amp;gt;1&amp;lt;/przelicznik&amp;gt;&lt;br /&gt;&amp;lt;kod_waluty&amp;gt;AUD&amp;lt;/kod_waluty&amp;gt;&lt;br /&gt;&amp;lt;kurs_sredni&amp;gt;1,9339&amp;lt;/kurs_sredni&amp;gt;&lt;br /&gt;&amp;lt;/pozycja&amp;gt;&lt;br /&gt;&amp;lt;pozycja&amp;gt;&lt;br /&gt;&amp;lt;nazwa_waluty&amp;gt;dolar Hongkongu&amp;lt;/nazwa_waluty&amp;gt;&lt;br /&gt;&amp;lt;przelicznik&amp;gt;1&amp;lt;/przelicznik&amp;gt;&lt;br /&gt;&amp;lt;kod_waluty&amp;gt;HKD&amp;lt;/kod_waluty&amp;gt;&lt;br /&gt;&amp;lt;kurs_sredni&amp;gt;0,2649&amp;lt;/kurs_sredni&amp;gt;&lt;br /&gt;&amp;lt;/pozycja&amp;gt;&lt;br /&gt;&amp;lt;pozycja&amp;gt;&lt;br /&gt;&amp;lt;nazwa_waluty&amp;gt;dolar kanadyjski&amp;lt;/nazwa_waluty&amp;gt;&lt;br /&gt;&amp;lt;przelicznik&amp;gt;1&amp;lt;/przelicznik&amp;gt;&lt;br /&gt;&amp;lt;kod_waluty&amp;gt;CAD&amp;lt;/kod_waluty&amp;gt;&lt;br /&gt;&amp;lt;kurs_sredni&amp;gt;2,0138&amp;lt;/kurs_sredni&amp;gt;&lt;br /&gt;&amp;lt;/pozycja&amp;gt;&lt;br /&gt;&amp;lt;pozycja&amp;gt;&lt;br /&gt;&amp;lt;nazwa_waluty&amp;gt;dolar nowozelandzki&amp;lt;/nazwa_waluty&amp;gt;&lt;br /&gt;&amp;lt;przelicznik&amp;gt;1&amp;lt;/przelicznik&amp;gt;&lt;br /&gt;&amp;lt;kod_waluty&amp;gt;NZD&amp;lt;/kod_waluty&amp;gt;&lt;br /&gt;&amp;lt;kurs_sredni&amp;gt;1,5061&amp;lt;/kurs_sredni&amp;gt;&lt;br /&gt;&amp;lt;/pozycja&amp;gt;&lt;br /&gt;&amp;lt;/tabela_kursow&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;color:#009900;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;Potrzebne będą jeszcze tabele które będą przechowywać dane. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;USE tempdb&lt;br /&gt;GO&lt;br /&gt;CREATE TABLE dbo.WALUTY (&lt;br /&gt;KOD_WALUTY CHAR(3) PRIMARY KEY NOT NULL,&lt;br /&gt;NAZWA_WALUTY VARCHAR(100) NOT NULL&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;CREATE TABLE dbo.KURSY_WALUT (&lt;br /&gt;KOD_WALUTY CHAR(3) NOT NULL,&lt;br /&gt;KURS_SREDNI MONEY NOT NULL,&lt;br /&gt;DATA DATETIME NOT NULL,&lt;br /&gt;PRZELICZNIK SMALLINT NOT NULL,&lt;br /&gt;PRIMARY KEY (KOD_WALUTY, DATA),&lt;br /&gt;FOREIGN KEY (KOD_WALUTY) REFERENCES dbo.WALUTY (KOD_WALUTY)&lt;br /&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Musimy jeszcze zadeklarować zmienną, która będzie przechowywała nasz dokument XML. Zmienna ta jest typu XML.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;DECLARE @XMLDATA AS XML&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Aby załadować zawartość pliku XMl do naszej zmeinnej skorzystamy z funkcji OPENROWSET. W SQL Server 2005 funkcja OPENROWSET umożliwia czytanie zawartości pliku bez konieczności korzystania z tabeli. Dzięki korzystamy tylko z jednej istrukcji SELECT.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;SELECT @XMLDATA = X FROM OPENROWSET(BULK 'C:\NBP.xml', SINGLE_BLOB) AS IMPORT(X).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Mając utworzone tabele oraz zadeklarowaną zmienna przechowującą zawartość pliku XML możemy przejść do przetwarzania tych danych. W tym celu wykorzystamy procedure, która jako parametr będzie przyjmowała naszą zmienną XML, a raczej dokument XML, który załadowaliśmy wcześniej do zmiennej.&lt;br /&gt;Procedura przyjmuje dokument XML jako swój parametr a nie scieżkę do pliku. Jest to o tyle istotne, że procedura ta może być wykorzystana w dowolnej aplikacji, która będzie przekazyła dokument XML jako łańcuch znaków. Aplikacja taka może np codziennie pobierać dane bezpośrednio ze stron NBP, i przekazywać zawarośc dokumentu do procedury, bez konieczności materializowania pliku na dysku. O tym jak łatwo można zamienić Dataset w aplikacji .NET do łańcucha znaków kilka słów poświęcę na koniec tego dokumentu.&lt;br /&gt;Nazwijmy naszą procedurę IMPORT_NBP&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;CREATE PROCEDURE IMPORT_NBP(&lt;br /&gt;@XMLDATA XML&lt;br /&gt;)&lt;br /&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Na początek musimy zadeklarować zmienną oraz tymczasową tabelę, które pomogą nam w przetwarzaniu danych.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;DECLARE @DATA_PUBLIKACJI AS DATETIME&lt;br /&gt;&lt;br /&gt;CREATE TABLE #KURSY_WALUT (&lt;br /&gt;NAZWA_WALUTY NVARCHAR(100),&lt;br /&gt;PRZELICZNIK SMALLINT,&lt;br /&gt;KOD_WALUTY CHAR(3),&lt;br /&gt;KURS_SREDNI MONEY&lt;br /&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Data publikacji występuje w naszym dokumencie XMl tylko raz. Aby kod był bardziej czytelny będziemy tę wartość przechowywać w zmiennej DATA_PUBLIKACJI.&lt;br /&gt;Tymczasowa tabela KURSY_WALUT będzie przechowywała tymczasowo zawartość naszych elementów XML.&lt;br /&gt;W celu przypisania wartości zmeinnej DATA_PUBLIKACJI skorzystamy z funkcji value.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;SELECT @DATA_PUBLIKACJI = X.value('(/tabela_kursow/data_publikacji/text())[1]', 'DATETIME') FROM @XMLDATA.nodes('.') AS IMPORT(X)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Proszę zwrócić uwagę na fakt, że funkcja value jak i wszystkiego pozostałe fukcje oraz elementy XML są pisane małymi literami. XML rozróżnia wielkość liter. Funkcja text() odczytuje zawartość elementu data_publikacji. Proszę zwrócić uwagę na index elementu [1]. Oznacza to, że funkcja value pobiera pierwszy element data_publikacji w dokumencie XML. Indeksowanie elementów rozpoczyna się od wartości 1, inaczej jak ma to miejsce w .NET Framework, gdzie indeksowanie rozpoczyna się domyślnie od 0. Jeżeli w naszym dokumecie występowałoby więcej elementów data_publikacji moglibyśmy użyć innej wartości indeksu. Zawartość naszego elementu data_publikacji odczytujemy jako DATETIME. Uzywając funkcji value musimy podać jakiego typu jest nasz element.&lt;br /&gt;Mając już datę publikacji przejdźmy do odczytywanie kolejnych danych. Teoretycznie moglibyśmy to zrobić w ten sam sposób jak odczytaliśmy datę, zmieniając tylko element XML z /tabela_kursow/data_publikacji na /tabela_kursow/pozycja/nazwa_valuty. Z praktycznego punktu widzenia jest to jednak zadanie bardzo karkołomne gdyz najpierw musielibyśmy znać ilość elementów w naszym dokumencie XML a później pobierać każdy z nich z osobna.&lt;br /&gt;Aby sprawić, żeby nasz kod był bardziej uniwersalny skorzystamy z dwóch dodatkowych funkcji, służących do przetwarzania dokumentów XML. Będą to funkcje query i nodes.&lt;br /&gt;Poniższe zapytanie zwróci nam wszystkie elementy pozycja z osobna.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;SELECT X.query('.') AS NODE FROM @XMLDATA.nodes('tabela_kursow/pozycja') AS IMPORT(X)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Teraz korzystając z kolejnego, zewnętrznego zapytania możemy pobrać wartości każdego z elementów naszego dokumentu XML. Wszystkie te dane wstawimy do naszej tabeli tymczasowej KURSY_WALUT.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;INSERT INTO #KURSY_WALUT (NAZWA_WALUTY, PRZELICZNIK, KOD_WALUTY, KURS_SREDNI) (&lt;br /&gt;SELECT&lt;br /&gt;NODE.value('(/pozycja/nazwa_waluty/text())[1]', 'NVARCHAR(100)'),&lt;br /&gt;NODE.value('(/pozycja/przelicznik/text())[1]', 'SMALLINT'),&lt;br /&gt;NODE.value('(/pozycja/kod_waluty/text())[1]', 'CHAR(3)'),&lt;br /&gt;REPLACE(NODE.value('(/pozycja/kurs_sredni/text())[1]', 'NVARCHAR(15)'), ',', '.')&lt;br /&gt;FROM (&lt;br /&gt;SELECT X.query('.') AS NODE FROM @XMLDATA.nodes('tabela_kursow/pozycja') AS IMPORT(X)&lt;br /&gt;) AS ELEMENTY&lt;br /&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;W tym miejscu poświęcę kilka słów średniemu kursowi wymiany. Nasz dokument XML przechowuje tę wartość formie liczby zmienno-pozcyjnej, używając jako separatora dziesiętnego przecinka. SQL Server 2005 domyślnie używa jako separatora kropki. Gdybyśmy odczytali wartośc kurs_sredni jako typ MONEY w naszej tabeli znaleźlibyśmy nie 1,9339 a 19339.00. Dlatego też odczytujemy tę wartość jako typ NVARCHAR, a funkcja REPLACE zatępuje znaki [,] na [.].&lt;br /&gt;W ten sposób mamy już nasze dane z pliku XML w tabeli tymczasowej.&lt;br /&gt;Na koniec pozostaje nam zapisanie wszystkich dancyh do naszych tabel docelowych.&lt;br /&gt;Najpierw zapisujemy dane do tabeli WALUTY, sprawdzając przy okazji czy podane waluta już nie istnieje w naszej bazie danych.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;INSERT INTO dbo.WALUTY (KOD_WALUTY, NAZWA_WALUTY) (&lt;br /&gt;SELECT KOD_WALUTY, NAZWA_WALUTY FROM #KURSY_WALUT&lt;br /&gt;WHERE KOD_WALUTY NOT IN (SELECT KOD_WALUTY FROM dbo.WALUTY)&lt;br /&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Mając uzupełnioną tabelę z walutami możemy zapisać kursy walut, przy okazji sprawdzając czy kurs waluty dla danego dnia już nie istnieje.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;INSERT INTO dbo.KURSY_WALUT (KOD_WALUTY, KURS_SREDNI, DATA, PRZELICZNIK) (&lt;br /&gt;SELECT KOD_WALUTY, KURS_SREDNI, @DATA_PUBLIKACJI, PRZELICZNIK FROM #KURSY_WALUT AS KW&lt;br /&gt;WHERE NOT EXISTS (&lt;br /&gt;SELECT KOD_WALUTY, DATA FROM KURSY_WALUT WHERE KOD_WALUTY = KW.KOD_WALUTY AND DATA = @DATA_PUBLIKACJI&lt;br /&gt;)&lt;br /&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Na koniec pozostaje nam usunięcie tabeli tymczasowej&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;DROP TABLE #KURSY_WALUT&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A także ostatnie&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;GO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pora teraz sprawidzić naszą procedurę.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;DECLARE @XMLDATA AS XML&lt;br /&gt;SELECT @XMLDATA = X FROM OPENROWSET(BULK 'C:\NBP.xml', SINGLE_BLOB) AS IMPORT(X)&lt;br /&gt;&lt;br /&gt;EXEC IMPORT_NBP @XMLDATA&lt;br /&gt;&lt;br /&gt;SELECT * FROM dbo.KURSY_WALUT&lt;br /&gt;SELECT * FROM dbo.WALUTY&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Jak już wspomniałem wcześniej procedura ta może zostać wykorzystana w aplikacji, która pobiera dane ze strony www, a później przekazuje cały dataset jako parametr w procedurze.&lt;br /&gt;Zamiana całego dataset w .NET na łańcuch znaków w formacie XML to tylko jedna instrukcja:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;Dataset1.GetXml&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;&lt;strong&gt;Podsumowanie&lt;/strong&gt;&lt;br /&gt;Jak widać na powyższym przykładzie w SQL Server 2005 bardzo łatwo możemy pzretwarzać dane w formacie XML. Dane nie muszą być przetwarzane w aplikacji, tylko wszystko przekazane zostaje na ‘barki’ serwera bazy danych.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;Na koniec kompletny kod naszej procedury.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#009900;"&gt;CREATE PROCEDURE IMPORT_NBP(&lt;br /&gt;@XMLDATA XML&lt;br /&gt;)&lt;br /&gt;AS&lt;br /&gt;&lt;br /&gt;DECLARE @DATA_PUBLIKACJI AS DATETIME&lt;br /&gt;&lt;br /&gt;CREATE TABLE #KURSY_WALUT (&lt;br /&gt;NAZWA_WALUTY NVARCHAR(100),&lt;br /&gt;PRZELICZNIK SMALLINT,&lt;br /&gt;KOD_WALUTY CHAR(3),&lt;br /&gt;KURS_SREDNI MONEY&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;SELECT @DATA_PUBLIKACJI = X.value('(/tabela_kursow/data_publikacji/text())[1]', 'DATETIME') FROM @XMLDATA.nodes('.') AS IMPORT(X)&lt;br /&gt;&lt;br /&gt;INSERT INTO #KURSY_WALUT (NAZWA_WALUTY, PRZELICZNIK, KOD_WALUTY, KURS_SREDNI) (&lt;br /&gt;SELECT&lt;br /&gt;NODE.value('(/pozycja/nazwa_waluty/text())[1]', 'NVARCHAR(100)'),&lt;br /&gt;NODE.value('(/pozycja/przelicznik/text())[1]', 'SMALLINT'),&lt;br /&gt;NODE.value('(/pozycja/kod_waluty/text())[1]', 'CHAR(3)'),&lt;br /&gt;REPLACE(NODE.value('(/pozycja/kurs_sredni/text())[1]', 'NVARCHAR(15)'), ',', '.')&lt;br /&gt;FROM (&lt;br /&gt;SELECT X.query('.') AS NODE FROM @XMLDATA.nodes('tabela_kursow/pozycja') AS IMPORT(X)&lt;br /&gt;) AS ELEMENTY&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;INSERT INTO dbo.WALUTY (KOD_WALUTY, NAZWA_WALUTY) (&lt;br /&gt;SELECT KOD_WALUTY, NAZWA_WALUTY FROM #KURSY_WALUT&lt;br /&gt;WHERE KOD_WALUTY NOT IN (SELECT KOD_WALUTY FROM dbo.WALUTY)&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;INSERT INTO dbo.KURSY_WALUT (KOD_WALUTY, KURS_SREDNI, DATA, PRZELICZNIK) (&lt;br /&gt;SELECT KOD_WALUTY, KURS_SREDNI, @DATA_PUBLIKACJI, PRZELICZNIK FROM #KURSY_WALUT AS KW&lt;br /&gt;WHERE NOT EXISTS (&lt;br /&gt;SELECT KOD_WALUTY, DATA FROM KURSY_WALUT WHERE KOD_WALUTY = KW.KOD_WALUTY AND DATA = @DATA_PUBLIKACJI&lt;br /&gt;)&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;DROP TABLE #KURSY_WALUT&lt;br /&gt;&lt;br /&gt;GO&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5256701949692196546-609404526318042361?l=updatedev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/UpdateDev/~4/pISIP0Ax_AQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://updatedev.blogspot.com/feeds/609404526318042361/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5256701949692196546&amp;postID=609404526318042361" title="Komentarze (2)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/609404526318042361?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5256701949692196546/posts/default/609404526318042361?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/UpdateDev/~3/pISIP0Ax_AQ/importowanie-danych-z-xml-do-bazy.html" title="Importowanie danych z XML do bazy danych." /><author><name>Grzegorz Gazda</name><uri>https://profiles.google.com/105510788952704126859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://updatedev.blogspot.com/2008/08/importowanie-danych-z-xml-do-bazy.html</feedburner:origLink></entry></feed>

