<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5007766622156228007</id><updated>2025-07-06T18:23:12.064+08:00</updated><category term="Stored Procedure"/><category term="Database Maintenance"/><category term="Development Guidelines"/><category term="MSSQL Tricks"/><category term="Database Design"/><category term="SQL Puzzle"/><category term="General Information"/><category term="Performance"/><category term="Function"/><category term="ASP.NET"/><category term="C#"/><category term="Index"/><category term="Security"/><category term="System Tables/Views"/><category term="Backup"/><category term="Trigger"/><category term="Date"/><category term="Deadlock"/><category term="Decision table"/><category term="Encryption"/><category term="Grid"/><category term="Login"/><category term="User ID"/><category term="Website"/><title type='text'>MSSQL Tips &amp;amp; Tricks</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>My 2022 blog</name><uri>http://www.blogger.com/profile/06421748148572963945</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>62</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-4462167796560969139</id><published>2021-05-14T12:43:00.003+08:00</published><updated>2021-05-14T12:43:51.232+08:00</updated><title type='text'>We are moving</title><content type='html'>&lt;p&gt;We are moving to our new blog site:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://ciysys.com/blog/mssql.htm&quot;&gt;https://ciysys.com/blog/mssql.htm&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/4462167796560969139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2021/05/we-are-moving.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/4462167796560969139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/4462167796560969139'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2021/05/we-are-moving.html' title='We are moving'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-101254888136668126</id><published>2021-01-12T18:03:00.001+08:00</published><updated>2021-01-12T18:03:01.434+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Decision table"/><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="SQL Puzzle"/><title type='text'>The decision table for discount process</title><content type='html'>&lt;style&gt;.md-content h1, .md-content h2, .md-content h3, .md-content h4,.md-content h5,.md-content h6 {margin: 1em 0 15px;padding: 0;font-weight: bold;line-height: 1.7;cursor: text;position: relative;color: hsl(0, 0%, 0%);}
.md-content h1 {font-size: 2.5em;border-bottom: 1px solid #ddd;}
.md-content h2 {font-size: 2em;border-bottom: 1px solid #eee;}
.md-content h3 {font-size: 1.5em;}
.md-content code, .md-content tt {margin: 0 2px;padding: 0px 5px;border: 1px solid #ddd;background-color: #f8f8f8;border-radius: 3px;}
.md-content code {white-space: nowrap;}
.md-content .highlight pre, .md-content pre {background-color: #f8f8f8;border: 1px solid #ddd;font-size: 13px;line-height: 19px;overflow: auto;padding: 6px 10px;border-radius: 3px;}
.md-content p, .md-content blockquote, .md-content ul, .md-content ol, .md-content dl, .md-content table, .md-content pre {margin: 15px 0;}
.md-content pre &gt; code {margin: 0;padding: 0;white-space: pre;border: none;background: transparent;}
.md-content pre code, .md-content pre tt {margin: 0;padding: 0;background-color: transparent;border: none;}
.md-content .tag {float: left;padding: 5px;margin-right: 5px;margin-bottom: 5px;;background-color: hsl(120, 90.5%, 41.2%);color: hsl(0, 0%, 100%);font-size: .8em;}
.md-content .tag &gt; p{margin:unset;}
.md-content .endtag {clear: both;}
.md-content li {margin-bottom: 4px;}
.md-content .alert {background-color: red !important;color: white;margin: 0 2px;padding: 0px 5px;border: 1px solid #ddd;background-color: #f8f8f8;border-radius: 3px;}
.md-content table {width: 100%;overflow: auto;display: block;border-spacing: 0;border-collapse: collapse;}
.md-content table tr {border-top: 1px solid #ccc;background-color: #fff;}
.md-content table th, .md-content table td {border: 1px solid #ddd;padding: 6px 13px;}
.md-content table tr:nth-child(2n) {background-color: #f8f8f8;}
&lt;/style&gt;&lt;div class=&quot;md-content&quot;&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;In the context of Point of sales (POS) for many industry, it is quite common that a shop might run promotion on different period, weekday and whether holiday should give discount or not. The discount process that we are discussing in this article is an automated process. Meaning that the cashier will scan the barcode of the item and the discount will be given automatically.&lt;/p&gt;
&lt;p&gt;To run a complex price discount process based on the date factor, the decision table will look like this:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align:center&quot;&gt;Rule #&lt;/th&gt;
&lt;th style=&quot;text-align:center&quot;&gt;Is holiday&lt;/th&gt;
&lt;th style=&quot;text-align:center&quot;&gt;Day of week&lt;/th&gt;
&lt;th style=&quot;text-align:center&quot;&gt;Exclude holiday&lt;/th&gt;
&lt;th style=&quot;text-align:center&quot;&gt;Include holidy&lt;/th&gt;
&lt;th style=&quot;text-align:center&quot;&gt;Give discount?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:center&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:center&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:center&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:center&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:center&quot;&gt;5&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:center&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:center&quot;&gt;7&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:center&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;n&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;y&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;The decision table explanations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&#39;Is holiday&#39; is a table that stores the date of holiday. This table is to be setup by the system admin.&lt;/li&gt;
&lt;li&gt;&#39;Day of week&#39;, &#39;exclude holiday&#39; and &#39;include holiday&#39; is a boolean (checkbox field on the scren) and the setting should be kept in the &#39;price discount&#39; table. This table is to be setup by the system admin as well.&lt;/li&gt;
&lt;li&gt;&#39;Day of week&#39; which has 7 fields that includes Monday, Tuesday, etc. &#39;y&#39;, means that week day has discount.&lt;/li&gt;
&lt;li&gt;&#39;Exclude holiday&#39; is a field that is used in conjunction with &#39;day of week&#39;.&lt;/li&gt;
&lt;li&gt;&#39;Include holiday&#39; is a field that is used in conjunction with &#39;day of week&#39; and it is mutually exclusive from &#39;exclude holiday&#39;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Use case&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Discount is applicable for weekdays (Monday to Friday) regardless holiday - rule #1 and #3 applies.&lt;/li&gt;
&lt;li&gt;Discount is applicable for weekdays (Monday to Friday) excluding holiday - rule #4 applies.&lt;/li&gt;
&lt;li&gt;Discount is applicable for weekdays (Monday to Friday) and applicable holiday - rule #5 applies.&lt;/li&gt;
&lt;li&gt;Discount is not applicable for weekdays (Monday to Friday) regardless holiday- rule #2 and #6 applies.&lt;/li&gt;
&lt;li&gt;Discount is not applicable for weekdays (Monday to Friday) and applicable on holiday - rule #8 applies.&lt;/li&gt;
&lt;li&gt;Rule #7 is invalid. So, we may ingore it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Table structure&lt;/h2&gt;
&lt;p&gt;We need three tables to store the master setup. One for the holiday, one for the product and another one for the discount. It&#39;s a one to many relationship between tb_prod and tb_discount.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;create table tb_holiday (
    dt datetime not null
);

create table tb_prod (
    prod_id int not null
    , price money not null
);

create table tb_discount (
    prod_id int not null        
    , start_dt datetime null
    , end_dt datetime null
    , discount_pct numeric(6,2) null
    , for_mon int null
    , for_tue int null
    , for_wed int null
    , for_thu int null
    , for_fri int null
    , for_sat int null
    , for_sun int null
    , exclude_holiday int null
    , include_holiday int null
)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Setting up the test data&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;delete from tb_holiday;
delete from tb_prod;
delete from tb_discount;

insert into tb_holiday (dt) values 
(&#39;2021-01-13&#39;);

insert into tb_prod (prod_id, price) values
(1, 100)
, (2, 200);

insert into tb_discount (prod_id, start_dt, end_dt, discount_pct
, for_mon, for_tue, for_wed, for_thu, for_fri, for_sat, for_sun
, exclude_holiday, include_holiday) values 
(1, &#39;2021-01-01&#39;, &#39;2021-01-31&#39;, 0.1
    , 1, 1, 1, 1, 1, 0, 0
    , 1, 0)
, (1, &#39;2021-02-01&#39;, &#39;2021-02-28&#39;, 0.15
    , 1, 1, 1, 1, 1, 0, 0
    , 1, 0)
, (1, &#39;2021-01-01&#39;, &#39;2021-01-31&#39;, 0.05
    , 0, 0, 0, 0, 0, 1, 1
    , 0, 1)
, (1, &#39;2021-01-01&#39;, &#39;2021-01-31&#39;, 0.03
	, 0, 0, 0, 0, 0, 1, 1
	, 0, 1);    
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;To query the discount for any product&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;declare
    @is_holiday int 
    , @dow int 
    , @curr_dt datetime 
    , @prod_id int

set @prod_id = 1
set @curr_dt = &#39;2021-01-11&#39;
set @dow = datepart(weekday, @curr_dt)

if exists(
    select *	
    from tb_holiday
    where dt = @curr_dt
)
begin
    set @is_holiday = 1
end
else
begin
    set @is_holiday = 0
end

select 
    discount_pct
from tb_discount d
where
    prod_id = @prod_id
    and @curr_dt between d.start_dt and d.end_dt
    and (			
        (@is_holiday = 1 and (d.include_holiday = 1 and d.exclude_holiday = 0))
        or ((
                   (@dow = 1 and d.for_sun = 1)
                or (@dow = 2 and d.for_mon = 1)
                or (@dow = 3 and d.for_tue = 1)
                or (@dow = 4 and d.for_wed = 1)
                or (@dow = 5 and d.for_thu = 1)
                or (@dow = 6 and d.for_fri = 1)
                or (@dow = 7 and d.for_sat = 1)
            ) 
            and (
                (@is_holiday = 0)
                or (@is_holiday = 1 
                    and (d.include_holiday = 1 or d.exclude_holiday = 0)
                )
        ))
    )
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The above query first is to identify the day of week and check to see if it is holiday.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Follow by filtering the discount record by prod ID and the period.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It then checks the day of week and holiday.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, returns the discount percentage.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test case (please change the value of @curr_dt in the query)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For @curr_dt = 2021-01-11 (Monday), the discount percentage is 10%. The week day discount in Jan 2021.&lt;/li&gt;
&lt;li&gt;For @curr_dt = 2021-01-13 (Wednesday, holiday), the discount percentage is 3%.&lt;/li&gt;
&lt;li&gt;For @curr_dt = 2021-01-16 (Saturday), the discount percentage is 5%. There is a caveat in the result because the query returns two discount records.&lt;/li&gt;
&lt;li&gt;For @curr_dt = 2021-02-11 (Thursday), the discount percentage is 15%. The week day discount in Feb 2021.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Caveat - there might be more than one discount record returned by the query. To avoid this from happening,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;During the discount setup time, you may have to prompt the user on the conflict OR&lt;/li&gt;
&lt;li&gt;In case the conflicting discount allows to be saved, you may have to return the latest discount record using TOP 1 + ORDER BY modified_on or any other condition that will force the query returning only one discount record.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/101254888136668126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2021/01/the-decision-table-for-discount-process.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/101254888136668126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/101254888136668126'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2021/01/the-decision-table-for-discount-process.html' title='The decision table for discount process'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-2757993490438798234</id><published>2019-11-28T16:23:00.001+08:00</published><updated>2019-11-28T16:23:11.810+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Database Design"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><title type='text'>Disabling auto-close in the database</title><content type='html'>If auto-close has been enabled in the database, it will have negative effects on the hard disk spinning load and also might flood the event log with &quot;starting database..&quot;. It has been widely discussed in the Internet why it&#39;s not a good idea to enable it.&lt;br /&gt;
&lt;br /&gt;
Anyway, here is the SQL script to disabled auto-close feature.&lt;br /&gt;
&lt;br /&gt;
set nocount on&lt;br /&gt;
&lt;br /&gt;declare&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @seq int&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; , @db sysname&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; , @sql nvarchar(max)&lt;br /&gt;&lt;br /&gt;select seq = row_number() over (order by name), name&lt;br /&gt;into #db_list&lt;br /&gt;from sys.databases&lt;br /&gt;where is_auto_close_on = 1&lt;br /&gt;&lt;br /&gt;set @seq = 0&lt;br /&gt;&lt;br /&gt;while exists(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; select *&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; from #db_list&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; where seq &amp;gt; @seq&lt;br /&gt;)&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; select top 1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; @seq = seq&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; , @db = name&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; from #db_list&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; where seq &amp;gt; @seq&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; order by seq&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; print &#39;reseting auto close for &#39; + @db&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set @sql = &#39;alter database &#39; + @db + &#39; set AUTO_CLOSE off&#39;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ----print @sql&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; exec sp_executesql @sql&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;print &#39;done&#39;&lt;br /&gt;&lt;br /&gt;drop table #db_list&lt;br /&gt;&lt;br /&gt;set nocount off&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/2757993490438798234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2019/11/disabling-auto-close-in-database.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/2757993490438798234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/2757993490438798234'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2019/11/disabling-auto-close-in-database.html' title='Disabling auto-close in the database'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-2432457141529351545</id><published>2019-10-18T16:46:00.002+08:00</published><updated>2019-10-18T16:46:47.673+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><title type='text'>Loop all records</title><content type='html'>&lt;br /&gt;
Basically, there is another way of looping which uses 
CURSOR. But, it requires record locking which may not work as fast as 
you think.&lt;br /&gt;
&lt;br /&gt;
In this article, we are going to use a temporary table to keep the data and then loop it with &quot;seq&quot; filter. The following example which is printing all table names on the screen. You may modify the PRINT line so that it compose the necessary SQL statement before you print it or execute any dynamic SQL.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
set nocount on&lt;br /&gt;&lt;br /&gt;declare&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;@seq int&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;, @name nvarchar(255)&lt;br /&gt;&lt;br /&gt;-- declare a temporary table in the memory.&lt;br /&gt;declare @tb table (&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;seq int identity(1,1)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;, name nvarchar(255)&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;--copy all the necessary records to the temporary table &#39;@tb&#39;&lt;br /&gt;insert into @tb (name)&lt;br /&gt;select name &lt;br /&gt;from sys.objects &lt;br /&gt;where &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;type = &#39;u&#39;and &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;name like &#39;tb_suggest%&#39;&lt;br /&gt;order by name&lt;br /&gt;&lt;br /&gt;-- init the var before use&lt;br /&gt;set @seq = 0&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- start the lopp&lt;br /&gt;while exists(&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;select *&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;from @tb&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;where seq &amp;gt; @seq&lt;br /&gt;)&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;-- always load the first record that is greater than&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;-- last seq.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;select top 1&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;--&amp;lt;&amp;lt;=== this is very important!!!&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;@seq = seq&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;, @name = name&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;from @tb&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;where seq &amp;gt; @seq&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;order by seq&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;--&amp;lt;&amp;lt;=== this is very important!!!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;-- do whatevery necessary process here.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;-- you may use &#39;set xxx&#39; to join the sql string before print it out.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;print &#39;@name =&amp;gt; &#39; + @name&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/2432457141529351545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2019/10/loop-all-records.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/2432457141529351545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/2432457141529351545'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2019/10/loop-all-records.html' title='Loop all records'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-3993932095864601382</id><published>2019-09-19T11:37:00.000+08:00</published><updated>2019-10-15T10:30:42.398+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="Index"/><title type='text'>How to find out which index is missing</title><content type='html'>To find out the missing index, we have to analyze the information in the following system views:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;sys.dm_db_missing_index_groups&lt;/li&gt;
&lt;li&gt;sys.dm_db_missing_index_group_stats&lt;/li&gt;
&lt;li&gt;sys.dm_db_missing_index_details &lt;/li&gt;
&lt;/ul&gt;
You may download the script that combine all the necessary information from the following URL:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; https://gist.github.com/alexsorokoletov/a079629f9e1435c7f81f&lt;br /&gt;
&lt;br /&gt;
And here is the SQL script:&lt;br /&gt;
&lt;br /&gt;
SELECT &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CONVERT (varchar, getdate(), 126) AS runtime, &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; mig.index_group_handle, mid.index_handle, &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CONVERT (decimal (28,1), migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans)) AS improvement_measure, &lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;CREATE INDEX missing_index_&#39; + CONVERT (varchar, mig.index_group_handle) + &#39;_&#39; + CONVERT (varchar, mid.index_handle) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; + &#39; ON &#39; + mid.statement &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; + &#39; (&#39; + ISNULL (mid.equality_columns,&#39;&#39;) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; + CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL THEN &#39;,&#39; ELSE &#39;&#39; END + ISNULL (mid.inequality_columns, &#39;&#39;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; + &#39;)&#39; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; + ISNULL (&#39; INCLUDE (&#39; + mid.included_columns + &#39;)&#39;, &#39;&#39;) AS create_index_statement, &lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; migs.*, mid.database_id, mid.[object_id]&lt;br /&gt;
&lt;br /&gt;
FROM sys.dm_db_missing_index_groups mig&lt;br /&gt;
INNER JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle&lt;br /&gt;
INNER JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle&lt;br /&gt;
&lt;br /&gt;
WHERE &lt;br /&gt;
CONVERT (decimal (28,1), migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans)) &amp;gt; 10&lt;br /&gt;
--and database_id =&amp;nbsp; DB_ID(&#39;my_database&#39;)&lt;br /&gt;
&lt;br /&gt;
ORDER BY migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;How to use it?&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;I&#39;m relying on improvement_measure value and I review the top 5 missing index information and then decide if I should create an index.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;We should not create all the indexes returned by this query. Because some of the missing indexes can be merge into one index.&lt;/li&gt;
&lt;li&gt;We should review the existing indexes and compare against what is missing and then decide the new index. This might involves deleting the existing index before creating a new one.&lt;/li&gt;
&lt;/ul&gt;
Life is tough with naming convention especially we want to know how many times that we have reviewed a particular index. My naming rule works this way:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;IX_my_table_1 - this is the first index.&lt;/li&gt;
&lt;li&gt;IX_my_table_2 - this is another index.&lt;/li&gt;
&lt;li&gt;IX_my_table_2_1 - this is the newer version of index where IX_my_table_2 has been dropped and merge with the new missing columns.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/3993932095864601382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2019/09/how-to-find-out-whic-index-is-missing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/3993932095864601382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/3993932095864601382'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2019/09/how-to-find-out-whic-index-is-missing.html' title='How to find out which index is missing'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-4915947922551405311</id><published>2019-09-14T11:13:00.001+08:00</published><updated>2019-09-14T11:13:34.082+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><title type='text'>Fixing the database state</title><content type='html'>&lt;br /&gt;
Sometimes after rebooting the server, the database state might stick in &quot;recovery&quot;. Waiting and waiting and rebooting might not change to the normal state.&lt;br /&gt;
&lt;br /&gt;
In this case, we need to fix this issue manually.&lt;br /&gt;
&lt;br /&gt;
To view the current database state:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; SELECT name, state_desc from sys.databases&lt;br /&gt;
&lt;br /&gt;
To fix the problematic database:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; ALTER DATABASE test SET EMERGENCY;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; GO&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; ALTER DATABASE test SET SINGLE_USER&lt;br /&gt;
&amp;nbsp;&amp;nbsp; GO&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; DBCC CHECKDB (test, REPAIR_ALLOW_DATA_LOSS) WITH ALL_ERRORMSGS;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; GO &lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; ALTER DATABASE test SET MULTI_USER&lt;br /&gt;
&amp;nbsp;&amp;nbsp; GO&lt;br /&gt;
&lt;br /&gt;
Before running the above commands, please make sure you have done sufficient research on the Internet before executing it!</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/4915947922551405311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2019/09/sometimes-after-rebooting-server.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/4915947922551405311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/4915947922551405311'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2019/09/sometimes-after-rebooting-server.html' title='Fixing the database state'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-2743367205887393762</id><published>2018-10-26T00:40:00.001+08:00</published><updated>2018-10-26T00:40:15.980+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><title type='text'>Running the same stored procedure sequentially</title><content type='html'>Use the following system stored procedure to block the same stored procedure from running concurrently.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; sp_getapplock&lt;br /&gt;
&lt;br /&gt;
Finally, you must call the following so that next process is allowed to run the same stored procedure.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; sp_releaseapplock&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;The above system stored procedures must be running within a database transaction.&lt;/li&gt;
&lt;li&gt;If @@lock_timeout is -1, then, sp_getapplock will be block until it has been released and commit/rollback must be called.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;If @@lock_timeout is not -1, then, the result will be less than zero (failed). But, sometimes it returns &quot;&amp;gt; 0&quot; (i.e., successfully get he app lock) and on the other hand it might fail to lock the &quot;record in the table&quot;. In this case, error #1222 will be raised by SQL server.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/2743367205887393762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2018/10/running-same-stored-procedure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/2743367205887393762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/2743367205887393762'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2018/10/running-same-stored-procedure.html' title='Running the same stored procedure sequentially'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-7451619015579844334</id><published>2018-10-15T10:03:00.001+08:00</published><updated>2018-10-26T00:20:31.384+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><category scheme="http://www.blogger.com/atom/ns#" term="Deadlock"/><title type='text'>Getting the deadlock details</title><content type='html'>In SQL 2012, you may query the deadlock details with the following SQL statement:&lt;br /&gt;
&lt;br /&gt;
SELECT XEvent.query(&#39;(event/data/value/deadlock)[1]&#39;) AS DeadlockGraph &lt;br /&gt;
FROM ( SELECT XEvent.query(&#39;.&#39;) AS XEvent &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM ( SELECT CAST(target_data AS XML) AS TargetData &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM sys.dm_xe_session_targets st &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JOIN sys.dm_xe_sessions s &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ON s.address = st.event_session_address &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHERE s.name = &#39;system_health&#39; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AND st.target_name = &#39;ring_buffer&#39; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) AS Data &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CROSS APPLY &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TargetData.nodes &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&#39;RingBufferTarget/event[@name=&quot;xml_deadlock_report&quot;]&#39;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AS XEventData ( XEvent ) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) AS src;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following query is for SQL2008:&lt;br /&gt;
&lt;br /&gt;
SELECT&amp;nbsp; CAST(event_data.value(&#39;(event/data/value)[1]&#39;,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;varchar(max)&#39;) AS XML) AS DeadlockGraph&lt;br /&gt;
FROM&amp;nbsp;&amp;nbsp;&amp;nbsp; ( SELECT&amp;nbsp;&amp;nbsp;&amp;nbsp; XEvent.query(&#39;.&#39;) AS event_data&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&amp;nbsp;&amp;nbsp;&amp;nbsp; -- Cast the target_data to XML &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT&amp;nbsp;&amp;nbsp;&amp;nbsp; CAST(target_data AS XML) AS TargetData&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sys.dm_xe_session_targets st&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JOIN sys.dm_xe_sessions s&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ON s.address = st.event_session_address&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHERE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name = &#39;system_health&#39;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AND target_name = &#39;ring_buffer&#39;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) AS Data -- Split out the Event Nodes &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CROSS APPLY TargetData.nodes(&#39;RingBufferTarget/&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; event[@name=&quot;xml_deadlock_report&quot;]&#39;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AS XEventData ( XEvent )&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) AS tab ( event_data ) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more details about deadlock and resolution, please read the following article:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://www.red-gate.com/simple-talk/sql/database-administration/handling-deadlocks-in-sql-server/&quot;&gt;https://www.red-gate.com/simple-talk/sql/database-administration/handling-deadlocks-in-sql-server/&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://www.red-gate.com/products/dba/sql-monitor/resources/articles/monitor-sql-deadlock&quot;&gt;https://www.red-gate.com/products/dba/sql-monitor/resources/articles/monitor-sql-deadlock&lt;/a&gt;&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/7451619015579844334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2018/10/getting-deadlock-details.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/7451619015579844334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/7451619015579844334'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2018/10/getting-deadlock-details.html' title='Getting the deadlock details'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-8298641786750991103</id><published>2016-12-22T14:51:00.003+08:00</published><updated>2016-12-22T14:53:19.916+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><category scheme="http://www.blogger.com/atom/ns#" term="System Tables/Views"/><title type='text'>Something about deadlock</title><content type='html'>This is a nice article that talks about how to find more details about deadlock.&lt;br /&gt;
&lt;br /&gt;
Finding and Extracting deadlock information using Extended Events&lt;br /&gt;
&lt;br /&gt;
http://social.technet.microsoft.com/wiki/contents/articles/31280.finding-and-extracting-deadlock-information-using-extended-events.aspx&lt;br /&gt;
&lt;br /&gt;
Using TRY/CATCH to handle the deadlock&lt;br /&gt;
&lt;br /&gt;
https://technet.microsoft.com/en-us/library/aa175791(v=sql.80).aspx&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/8298641786750991103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2016/12/deadlock.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/8298641786750991103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/8298641786750991103'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2016/12/deadlock.html' title='Something about deadlock'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-4369908498989595882</id><published>2016-12-22T11:44:00.000+08:00</published><updated>2016-12-22T11:44:06.414+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><title type='text'>Wait for a while..</title><content type='html'>&lt;br /&gt;
Here is the code that you need to put your process into sleep mode:&lt;br /&gt;
&lt;br /&gt;
declare @wait_time nvarchar(255)&lt;br /&gt;&lt;br /&gt;print &#39;start working on it.. =&amp;gt; current ms: &#39; + cast(datepart(millisecond, getdate()) as nvarchar)&lt;br /&gt;&lt;br /&gt;set @wait_time = &#39;00:00:00.&#39; + left(cast(cast(rand() * 1000 as int) as nvarchar), 3)&lt;br /&gt;waitfor delay @wait_time&lt;br /&gt;&lt;br /&gt;print &#39;im done and waited for &#39; + @wait_time&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; + &#39; =&amp;gt; current ms: &#39;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; + cast(datepart(millisecond, getdate()) as nvarchar)&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/4369908498989595882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2016/12/wait-for-while.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/4369908498989595882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/4369908498989595882'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2016/12/wait-for-while.html' title='Wait for a while..'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-217865756356290214</id><published>2015-06-23T11:41:00.001+08:00</published><updated>2015-06-23T11:41:37.902+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><title type='text'>Concatenating the records and use appropriate separator</title><content type='html'>If we have 4 records, we want to concatenate all 4 records and the last separator should be &quot;&amp;amp;&quot; symbol. We can achieve this by using row_number() function and then decide whether the separator is &quot;,&quot; or &quot;&amp;amp;&quot;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
declare @s nvarchar(max)&lt;br /&gt;&lt;br /&gt;create table #tb1 (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; email nvarchar(255)&lt;br /&gt;)&lt;br /&gt;insert into #tb1 values (&#39;a@a.com&#39;);&lt;br /&gt;insert into #tb1 values (&#39;b@a.com&#39;);&lt;br /&gt;insert into #tb1 values (&#39;c@a.com&#39;);&lt;br /&gt;insert into #tb1 values (&#39;d@a.com&#39;);&lt;br /&gt;&lt;br /&gt;select &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @s = coalesce(@s &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; + case when rowidx &amp;lt; cnt then &#39;,&#39; else &#39; &amp;amp; &#39; end&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; + email, email)&lt;br /&gt;from (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; select &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; rowidx=row_number() over( order by email )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; , email&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; , cnt = (select count(*) from tb1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; from #tb1&lt;br /&gt;) as a&lt;br /&gt;&lt;br /&gt;select @s&lt;br /&gt;&lt;br /&gt;drop table #tb1&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/217865756356290214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2015/06/concatenating-records-and-use.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/217865756356290214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/217865756356290214'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2015/06/concatenating-records-and-use.html' title='Concatenating the records and use appropriate separator'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-8900841643762411143</id><published>2013-11-25T15:43:00.001+08:00</published><updated>2013-11-25T15:43:46.784+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Database Design"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><category scheme="http://www.blogger.com/atom/ns#" term="General Information"/><category scheme="http://www.blogger.com/atom/ns#" term="Stored Procedure"/><category scheme="http://www.blogger.com/atom/ns#" term="System Tables/Views"/><title type='text'>Code sharing</title><content type='html'>I&#39;ve been thinking of sharing my codes for many years and finally I decided to do it.&lt;br /&gt;
&lt;br /&gt;
I have uploaded the table structures, views, stored procedures and functions into Github. You may download and use it freely. I will update the contents if I encounter the useful script and table design.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;a href=&quot;https://github.com/lauhw/MSSQLProc&quot; target=&quot;_blank&quot;&gt;https://github.com/lauhw/MSSQLProc&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Let me know if you have anything to share with me. ;)</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/8900841643762411143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2013/11/code-sharing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/8900841643762411143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/8900841643762411143'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2013/11/code-sharing.html' title='Code sharing'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-3275110286675040823</id><published>2013-08-20T10:42:00.000+08:00</published><updated>2013-08-20T10:42:00.576+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><title type='text'>Get the Guid.Empty constant in MS SQL</title><content type='html'>The following function returns the Guid.Empty (.Net constant) in MS SQL:&lt;br /&gt;
&lt;br /&gt;
create function dbo.fn_empty_guid ()&lt;br /&gt;returns uniqueidentifier&lt;br /&gt;as&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; declare &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; @result uniqueidentifier&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set @result = cast(cast(0 as varbinary) as uniqueidentifier)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return @result&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;end&lt;br /&gt;go&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Usage:&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
select dbo.fn_empty_guid()&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/3275110286675040823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2013/08/get-guidempty-constant-in-ms-sql.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/3275110286675040823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/3275110286675040823'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2013/08/get-guidempty-constant-in-ms-sql.html' title='Get the Guid.Empty constant in MS SQL'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-4168286595220315436</id><published>2013-04-25T22:24:00.001+08:00</published><updated>2013-04-25T22:24:26.906+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="General Information"/><category scheme="http://www.blogger.com/atom/ns#" term="SQL Puzzle"/><title type='text'>Lock or no lock</title><content type='html'>While I was reviewing other programmer&#39;s work, I found out that most of the SELECT statements contain this keyword - &quot;WITH (NOLOCK)&quot;. So, I posted this question to the programmer who is handling the job. His answer is quite simple, &quot;we need this to reduce the query response time and then our program will run faster&quot;. And the actual fact is that, the programmer does not know the side effect of this keyword.&lt;br /&gt;
&lt;br /&gt;
Yes, the query will run faster because it does not require to lock all the necessary records before reading it from the table. But, the side effects is that the data returned by the query might be &quot;dirty&quot; (i.e., the changes have not been committed).&lt;br /&gt;
&lt;br /&gt;
If the program has read the data which have been rolled back by other user, it could lead to many unpredictable situation. This could lead to unsolvable mystery.&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/4168286595220315436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2013/04/lock-or-no-lock.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/4168286595220315436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/4168286595220315436'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2013/04/lock-or-no-lock.html' title='Lock or no lock'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-3941999070174581821</id><published>2013-02-21T14:07:00.002+08:00</published><updated>2013-02-21T14:07:32.739+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><category scheme="http://www.blogger.com/atom/ns#" term="SQL Puzzle"/><category scheme="http://www.blogger.com/atom/ns#" term="Stored Procedure"/><title type='text'>Concatenate all records into one line text</title><content type='html'>Below is the code that you can use for concatenating all records into one line text: &lt;br /&gt;
&lt;br /&gt;declare @s nvarchar(max)&lt;br /&gt;&lt;br /&gt;select &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @s = coalesce(@s + &#39;,&#39; + prod_code, prod_code)&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;from prod&lt;br /&gt;&lt;br /&gt;select @s&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/3941999070174581821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2013/02/concatenate-all-records-into-one-line.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/3941999070174581821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/3941999070174581821'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2013/02/concatenate-all-records-into-one-line.html' title='Concatenate all records into one line text'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-2919555073727681113</id><published>2013-01-11T22:31:00.001+08:00</published><updated>2013-01-11T22:31:33.672+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Database Design"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="General Information"/><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><category scheme="http://www.blogger.com/atom/ns#" term="Performance"/><category scheme="http://www.blogger.com/atom/ns#" term="Stored Procedure"/><title type='text'>Using dynamic SQL for reporting process</title><content type='html'>What is the user requirements for the report?&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Lots of criteria on the screen but most of them are optional.&lt;/li&gt;
&lt;li&gt;The final result is a subset of a result.&lt;/li&gt;
&lt;li&gt;User allows to choose different sorting order.&lt;/li&gt;
&lt;li&gt;User allows to choose different grouping.&lt;/li&gt;
&lt;li&gt;The fields in the report was specified by the user at runtime.&lt;/li&gt;
&lt;/ul&gt;
By using dynamic SQL, you will be able to compose the appropriate SQL statement and then meets the user expectation. Another thing is that, you don&#39;t need to have many static SQL statements in the stored procedure.&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/2919555073727681113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2013/01/using-dynamic-sql-for-reporting-process.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/2919555073727681113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/2919555073727681113'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2013/01/using-dynamic-sql-for-reporting-process.html' title='Using dynamic SQL for reporting process'/><author><name>My 2022 blog</name><uri>http://www.blogger.com/profile/06421748148572963945</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-5115148692181085140</id><published>2012-10-22T09:00:00.000+08:00</published><updated>2012-10-22T09:00:01.901+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Backup"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Design"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="General Information"/><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><category scheme="http://www.blogger.com/atom/ns#" term="Security"/><category scheme="http://www.blogger.com/atom/ns#" term="SQL Puzzle"/><category scheme="http://www.blogger.com/atom/ns#" term="Stored Procedure"/><category scheme="http://www.blogger.com/atom/ns#" term="System Tables/Views"/><title type='text'>Dynamic SQL usage</title><content type='html'>One of the usefulness about dynamic SQL is for database maintenance. For example, you want to run the maintenance process in the selected databases.&lt;br /&gt;&lt;br /&gt;
Below is the flow of using dynamic SQL to ease the maintenance:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Create a table that stores the database names for your system.&lt;/li&gt;
&lt;li&gt;Declare a cursor and loop through all your database names and match the process number (explain later).&lt;/li&gt;
&lt;li&gt;Generate the dynamic SQL statement to be executed against the selected databases.&lt;/li&gt;
&lt;li&gt;Finally, execute the dynamic SQL.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
The reason to have a table to stores your database names:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;You are not interested in all databases stored in sys.databases. You just want to run the script against the selected databases.&lt;/li&gt;
&lt;li&gt;The database name did not follow any convention before you take over the maintenance. In you are handling the database server, then, you should follow a standard naming convention for the database name. This allows you to query the database name from sys.databases.&lt;/li&gt;
&lt;li&gt;You don&#39;t want to execute the SQL statement against all your application databases. Only certain databases are going to run script 1 and other databases are going to run script 2, etc.&lt;/li&gt;
&lt;/ul&gt;
The table design to stores the database name:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;db_name nvarchar(255) - this is the database name&lt;/li&gt;
&lt;li&gt;process_1 int - if &#39;1&#39; means run the maintenance stored procedure #1. &#39;0&#39; to ignore.&lt;/li&gt;
&lt;li&gt;process_2 int - if &#39;1&#39; means run the maintenance stored procedure #2.&#39;0&#39; to ignore.&lt;/li&gt;
&lt;li&gt;(other process flag).&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/5115148692181085140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/10/dynamic-sql-usage.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/5115148692181085140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/5115148692181085140'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/10/dynamic-sql-usage.html' title='Dynamic SQL usage'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-418343900019383557</id><published>2012-10-15T09:00:00.000+08:00</published><updated>2012-10-15T09:00:03.925+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Database Design"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="General Information"/><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><category scheme="http://www.blogger.com/atom/ns#" term="Performance"/><category scheme="http://www.blogger.com/atom/ns#" term="Stored Procedure"/><title type='text'>Executing dynamic SQL </title><content type='html'>In MSSQL, it is able to execute dynamic SQL. Meaning, you are allowed to execute the SQL statement that stores in a variable by calling sp_executesql system stored procedure. It compiles the SQL statement at runtime and then execute it. You may also create parameterized SQL statement so that it compiles once and run multiple times (for example, inserting many records within a loop).&lt;br /&gt;
&lt;br /&gt;
Whenever it&#39;s possible, try to avoid using the dynamic SQL. This is because each time you are executing the dynamic SQL statement (not within a loop in the stored procedure), it will be recompiled and increase the execution time.&lt;br /&gt;
&lt;br /&gt;
The advantage of implementing this idea will save you from having a permanent table to store the reporting data&amp;nbsp; or data for the current session. Also, it saves you having tuning the SQL statement with complex WHERE clause where some of the conditions were optional.  &lt;br /&gt;
&lt;br /&gt;
The following sample code returns all the object ID-s in the database by using the dynamic SQL statement. &lt;br /&gt;
&lt;br /&gt;
declare @sql nvarchar(max)&lt;br /&gt;
&lt;br /&gt;
select @sql = &#39;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; declare @tb table ( id int )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; insert into @tb (id)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; select object_id from sys.objects&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; select * from @tb &lt;br /&gt;
&#39;&lt;br /&gt;
exec sp_executesql @sql&lt;br /&gt;
&lt;br /&gt;
I will discuss a bit more in detail in my next article.</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/418343900019383557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/10/executing-dynamic-sql.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/418343900019383557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/418343900019383557'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/10/executing-dynamic-sql.html' title='Executing dynamic SQL '/><author><name>My 2022 blog</name><uri>http://www.blogger.com/profile/06421748148572963945</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-4953778960318413635</id><published>2012-10-08T09:00:00.000+08:00</published><updated>2012-10-08T09:00:00.307+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Design"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="General Information"/><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><category scheme="http://www.blogger.com/atom/ns#" term="SQL Puzzle"/><category scheme="http://www.blogger.com/atom/ns#" term="Stored Procedure"/><title type='text'>Generating &quot;reminder&quot; for the user</title><content type='html'>In a mid to large scale application, often you need to run scheduled tasks which can be schedule through the SQL Agent. One type of the schedule is to generate reminder or alert for the user. For example, inform the collection department about the overdue invoice.&lt;br /&gt;
&lt;br /&gt;
Below is the strategy to implement this type of process:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Create a stored procedures to scan the data.&lt;/li&gt;
&lt;li&gt;In this stored procedure, it contains the business logic about what data will meet the requirement and then generate the reminder record.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;The reminder record will be saved into tb_mail (this table stores the email to be pickup by a C# program).&lt;/li&gt;
&lt;li&gt;Develop a program in the C# application which will send all the emails in tb_mail table.&lt;/li&gt;
&lt;/ol&gt;
In case you don&#39;t want to notify the user through email, you may append this reminder record into an &quot;alert&quot; table (which can be &quot;tb_log&quot; table in our design). Then, display the alerts upon user login.&lt;br /&gt;
&lt;br /&gt;
For those alert requires immediate attention, you may send the reminder or alert through SMS (short messaging).</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/4953778960318413635/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/10/generating-reminder-for-user.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/4953778960318413635'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/4953778960318413635'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/10/generating-reminder-for-user.html' title='Generating &quot;reminder&quot; for the user'/><author><name>My 2022 blog</name><uri>http://www.blogger.com/profile/06421748148572963945</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-1373216920467231788</id><published>2012-10-01T09:00:00.000+08:00</published><updated>2012-10-01T09:00:02.915+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Database Design"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="General Information"/><category scheme="http://www.blogger.com/atom/ns#" term="Security"/><category scheme="http://www.blogger.com/atom/ns#" term="Stored Procedure"/><title type='text'>Benefits of using stored procedure instead of writing codes in C#</title><content type='html'>Started from my favorite programming language, Visual Basic 6 (that was in 1997), I&#39;ve been thinking where is the best place to implement the &quot;business rule&quot;. After many years of moving the business rules from the the programming language to the database and vice versa, I&#39;ve finally decided the best place for the business rule is in the stored procedure.&lt;br /&gt;
&lt;br /&gt;
The simplest stored procedure is for SELECT, INSERT, UPDATE and DELETE. Indeed, you can do more than that. Benefits of using the stored procedure:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Create audit log when doing any of the CRUD operation.&lt;/li&gt;
&lt;li&gt;Able to implement sophisticated control in what kind of data can be return to caller. &lt;/li&gt;
&lt;li&gt;Easier to enhance/process the records before returning the records.&lt;/li&gt;
&lt;li&gt;Stored procedure has been compiled and it runs faster than the ad-hoc query.&lt;/li&gt;
&lt;li&gt;Able to enhance the stored procedure at anytime.&lt;/li&gt;
&lt;li&gt;You don&#39;t have to recompile the application if there are any changes in the rule.&lt;/li&gt;
&lt;li&gt;You don&#39;t have to redistribute the application (at client workstation or web server) if there are any changes in the rule.&lt;/li&gt;
&lt;/ul&gt;
Well, I know that you might not 100% agree with my argument. But, as a customize solution builder like me, we can&#39;t ask all the users to stop for a while and wait for the latest update.</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/1373216920467231788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/10/benefits-of-using-stored-procedure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/1373216920467231788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/1373216920467231788'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/10/benefits-of-using-stored-procedure.html' title='Benefits of using stored procedure instead of writing codes in C#'/><author><name>My 2022 blog</name><uri>http://www.blogger.com/profile/06421748148572963945</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-1536312401792781544</id><published>2012-09-27T12:18:00.000+08:00</published><updated>2012-09-27T12:18:57.021+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><category scheme="http://www.blogger.com/atom/ns#" term="SQL Puzzle"/><title type='text'>Generate a series of number</title><content type='html'>Below is a way to generate a series of number (10 records where the value starts from 1 to 10) with Common Table Expression (CTE):&lt;br /&gt;
&lt;br /&gt;
with tb (ii)&lt;br /&gt;as (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; select &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 1 ii&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; union all&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; select ii + 1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; from tb&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; where ii + 1 &amp;lt;= 10&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;select *&lt;br /&gt;from tb&lt;br /&gt;
&lt;br /&gt;
For the detailed explanation, check this out:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.databasejournal.com/features/mssql/article.php/3502676/Common-Table-Expressions-CTE-on-SQL-2005.htm&quot;&gt;http://www.databasejournal.com/features/mssql/article.php/3502676/Common-Table-Expressions-CTE-on-SQL-2005.htm&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;When to use it&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use CTE + UNION ALL to generate hierarchical result. For example, you have a discussion forum where it allows the members to post question (a thread) with many replies (many level of sub-threads).&lt;/li&gt;
&lt;li&gt;Reduce re-typing the same SELECT statement especially you are aggregating the data.&lt;/li&gt;
&lt;/ul&gt;
</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/1536312401792781544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/09/generate-series-of-number.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/1536312401792781544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/1536312401792781544'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/09/generate-series-of-number.html' title='Generate a series of number'/><author><name>LAUHW</name><uri>http://www.blogger.com/profile/10348919377866511218</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuEii8GEsW2cLOV8Xey49K_2tklpoTI_72uHSFBGVotAuiy33aIL1nNyX5Kv7QCp2RWFJGPbd-ufiHfQDmDFvwJy1M93BQM5ovQbZO4dkMVsEWBXjBcdh3F1bTMuDFdI/s220/DSCN0706-small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-7631207313209723934</id><published>2012-09-20T00:14:00.001+08:00</published><updated>2012-09-20T00:14:23.242+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Design"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="Function"/><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><category scheme="http://www.blogger.com/atom/ns#" term="SQL Puzzle"/><category scheme="http://www.blogger.com/atom/ns#" term="Stored Procedure"/><title type='text'>Reading the system settings using stored procedure/function</title><content type='html'>&lt;br /&gt;
Stop hard-coding the constants in a stored procedure. Instead, you should read the value from your &quot;settings&quot; table or returning the constant value by a function call. In C# and other programming languages, you can declare constant in a class and use it anywhere in the program. But, in MSSQL, you can&#39;t do that.&lt;br /&gt;
&lt;br /&gt;
To get the constant or settings, you may try to do this:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Create a function which returns the value (could be constant or read a field from a table).&lt;/li&gt;
&lt;li&gt;Create a stored procedure and returns the value through OUTPUT parameter. &lt;/li&gt;
&lt;/ul&gt;
There are some factors which you might have to decide how to design the stored procedure/function:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Should the value configurable by the the user? If no, you may return the value by a function call. If the value is user configurable, then, you need a &quot;setting table&quot; to store the value.&lt;/li&gt;
&lt;li&gt;If the value must be stored in a table, do you store the value in a generic table structure (with prop_name and prop_value fields) OR do you need to design a &quot;settings&quot; table which contains only 1 record (with the appropriate field name which can reflect the setting)?&lt;/li&gt;
&lt;/ul&gt;
In our database design, we have a generic table that store setting. In case the values are frequently use, we will design a setting table to store the user configured values.&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/7631207313209723934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/09/reading-system-settings-using-stored.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/7631207313209723934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/7631207313209723934'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/09/reading-system-settings-using-stored.html' title='Reading the system settings using stored procedure/function'/><author><name>My 2022 blog</name><uri>http://www.blogger.com/profile/06421748148572963945</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-8614967362250096670</id><published>2012-09-10T09:00:00.000+08:00</published><updated>2012-09-10T09:00:02.860+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Database Design"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><category scheme="http://www.blogger.com/atom/ns#" term="SQL Puzzle"/><category scheme="http://www.blogger.com/atom/ns#" term="Stored Procedure"/><title type='text'>Show me the runtime value</title><content type='html'>In MSSQL, you may use PRINT statement to display some information when you are executing stored procedure or a SQL batch. This is very helpful to debug the stored procedure which contains many IF statements or you would like to find out the runtime value of certain variable.&lt;br /&gt;
&lt;br /&gt;
For example,&lt;br /&gt;
&lt;br /&gt;
declare @cust_name nvarchar(255)&lt;br /&gt;
&lt;br /&gt;
select @cust_name = cust_name&lt;br /&gt;
from tb_customer&lt;br /&gt;
where cust_code = &#39;A001&#39;&lt;br /&gt;
&lt;br /&gt;
print @cust_name&lt;br /&gt;
&lt;br /&gt;
When to use it:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Your stored procedure contains many IF statement and you want to know which path has been executed with different parameter value.&lt;/li&gt;
&lt;li&gt;You want to find out which stored procedure has been called when the main stored procedure has been executed.&lt;/li&gt;
&lt;li&gt;You want to find out what is the runtime value of the variables.&lt;/li&gt;
&lt;li&gt;You want to find out where is the process has exited.&lt;/li&gt;
&lt;/ul&gt;
</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/8614967362250096670/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/09/show-me-runtime-value.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/8614967362250096670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/8614967362250096670'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/09/show-me-runtime-value.html' title='Show me the runtime value'/><author><name>My 2022 blog</name><uri>http://www.blogger.com/profile/06421748148572963945</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-1326239855900205353</id><published>2012-09-03T09:00:00.000+08:00</published><updated>2012-09-03T09:00:01.765+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Database Design"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="General Information"/><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><category scheme="http://www.blogger.com/atom/ns#" term="SQL Puzzle"/><category scheme="http://www.blogger.com/atom/ns#" term="Stored Procedure"/><category scheme="http://www.blogger.com/atom/ns#" term="Trigger"/><title type='text'>Enabled debugging mode within the stored procedure without using parameter</title><content type='html'>In our previous &lt;a href=&quot;http://sqllauhw2000.blogspot.com/2012/08/allow-to-run-process-again.html&quot; target=&quot;_blank&quot;&gt;article&lt;/a&gt;, we discussed that the stored procedure should contain a parameter call &quot;@debug_mode&quot; so that it can be debug in the development phase. But, some people might feel that it makes the stored procedure looks ugly. In this article, we are going to show you another way to enable the debugging in the development without having this parameter. &lt;br /&gt;
&lt;br /&gt;
To store the information to the current session/connection, use the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; SET CONTEXT_INFO 0x1000&lt;br /&gt;
&lt;br /&gt;
To retrieve the value, use the following function:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; SELECT context_info()&lt;br /&gt;
&lt;br /&gt;
context_info able to store upto 128 bytes of information. The only thing is that you must learn how to work with bitwise operator.&lt;br /&gt;
&lt;br /&gt;
First thing you have to do with context_info is to define the meaning of each &quot;box&quot;. For example, you need to implement 4 hidden features. Then, the value will look like &quot;0x0000&quot; where &quot;0x&quot; indicates it is hex value and you can&#39;t use these two character to store any information. But, the 4 digits after &quot;0x&quot;, you are freely to define the meaning.&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;1st box - if &quot;1&quot; means enable the debugging mode. Otherwise, &quot;0&quot;.&lt;/li&gt;
&lt;li&gt;2nd box - could be defined as &quot;1&quot; to log down the process details.&lt;/li&gt;
&lt;li&gt;3rd box - could be defined as &quot;1&quot; to print the runtime value in the IDE.&lt;/li&gt;
&lt;li&gt;4th box - could be defined as &quot;1&quot; to rollback the process so that it won&#39;t disturb the test data.&lt;/li&gt;
&lt;/ul&gt;
Lastly, before you run your stored procedure, you have to call &quot;set context_info 0x1001&quot; to enable the debug mode and rollback the changes.&lt;br /&gt;
&lt;br /&gt;
Some modification is required in your stored procedure:&lt;br /&gt;
&lt;br /&gt;
declare&lt;br /&gt;
&amp;nbsp; @info varbinary(128),&lt;br /&gt;
&amp;nbsp; @debug_mode int,&lt;br /&gt;
&amp;nbsp; @rollback_data int&lt;br /&gt;
&lt;br /&gt;
select @info = context_info()&lt;br /&gt;
&lt;br /&gt;
if @info &amp;amp; 0x1000 = 0x1000&lt;br /&gt;
&amp;nbsp; select @debug_mode = 1&lt;br /&gt;
else&lt;br /&gt;
&amp;nbsp; select @debug_mode = 0&lt;br /&gt;
&lt;br /&gt;
if @info &amp;amp; 0x0001 = 0x0001&lt;br /&gt;
&amp;nbsp; select @rollback_data = 1&lt;br /&gt;
else&lt;br /&gt;
&amp;nbsp; select @rollback_data = 0&lt;br /&gt;
&lt;br /&gt;
(..contine your process here..)&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms187768.aspx&quot;&gt;http://msdn.microsoft.com/en-us/library/ms187768.aspx&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms176122.aspx&quot;&gt;http://msdn.microsoft.com/en-us/library/ms176122.aspx&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/1326239855900205353/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/09/enabled-debugging-mode-within-stored.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/1326239855900205353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/1326239855900205353'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/09/enabled-debugging-mode-within-stored.html' title='Enabled debugging mode within the stored procedure without using parameter'/><author><name>My 2022 blog</name><uri>http://www.blogger.com/profile/06421748148572963945</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5007766622156228007.post-5283518349948757880</id><published>2012-08-28T11:52:00.000+08:00</published><updated>2012-08-28T11:52:06.272+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Database Design"/><category scheme="http://www.blogger.com/atom/ns#" term="Database Maintenance"/><category scheme="http://www.blogger.com/atom/ns#" term="Development Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="MSSQL Tricks"/><category scheme="http://www.blogger.com/atom/ns#" term="SQL Puzzle"/><category scheme="http://www.blogger.com/atom/ns#" term="Stored Procedure"/><title type='text'>Allow to run the process again?</title><content type='html'>For the stored procedure that is executed by the SQL Agent (i.e., the scheduler), you might have to prevent the same stored procedure run more than once.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Allow re-entrant&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Not all processes allow to run more than once. For example, the 
stored procedure that is responsible for generating monthly statement. 
Another example is the stored procedure that is generating the exception
 report.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Why re-entrant&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&amp;nbsp; &lt;br /&gt;
In the development phase, you might want to run the stored procedure as many time as possible so that you can fine tune and debug the process. But, once these stored procedures go live, it will run once for the day, week, month or whatever predefined date.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Now, how to prevent re-entrant&lt;/b&gt;&lt;br /&gt;
In order to prevent the stored procedure to run more than once for a day, you need to have a condition to check the log table. In our example, the &quot;tb_whatever_process_log&quot; table is keeping track the process date.&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;if &lt;/span&gt;exists(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;select &lt;/span&gt;*&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;from &lt;/span&gt;tb_whatever_process_log &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;where&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; process_date = &lt;span style=&quot;color: magenta;&quot;&gt;cast&lt;/span&gt;(&lt;span style=&quot;color: magenta;&quot;&gt;convert&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;nvarchar&lt;/span&gt;, &lt;span style=&quot;color: magenta;&quot;&gt;getdate&lt;/span&gt;(), 102) &lt;span style=&quot;color: blue;&quot;&gt;as datetime&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt; begin&lt;/span&gt;&lt;br style=&quot;color: blue;&quot; /&gt;&lt;span style=&quot;color: blue;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; print&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;&#39;Already done. Exit&#39;&lt;/span&gt;&lt;br /&gt;&lt;br style=&quot;color: blue;&quot; /&gt;&lt;span style=&quot;color: blue;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; set nocount off&lt;/span&gt;&lt;br style=&quot;color: blue;&quot; /&gt;&lt;span style=&quot;color: blue;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/span&gt;&lt;br style=&quot;color: blue;&quot; /&gt;&lt;span style=&quot;color: blue;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (... continue with the actual process..)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;How to test this stored procedure?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Due to the re-entrant prevention condition, you will find it almost like no way to test out the stored procedure during the development phase. An easiest way to do this is to add a new parameter to the stored procedure call &quot;@debug_mode int = 0&quot;. In the development phase, you will have to specify the &quot;@debug_mode = 1&quot;.</content><link rel='replies' type='application/atom+xml' href='http://sqllauhw2000.blogspot.com/feeds/5283518349948757880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/08/allow-to-run-process-again.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/5283518349948757880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5007766622156228007/posts/default/5283518349948757880'/><link rel='alternate' type='text/html' href='http://sqllauhw2000.blogspot.com/2012/08/allow-to-run-process-again.html' title='Allow to run the process again?'/><author><name>My 2022 blog</name><uri>http://www.blogger.com/profile/06421748148572963945</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>