<?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: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-6400137361122596109</id><updated>2012-02-16T16:27:39.226+01:00</updated><category term='date last week'/><category term='All values'/><category term='Windows XP'/><category term='Vista'/><category term='EntropiaOnline'/><category term='wiki'/><category term='CHECKSUM'/><category term='web'/><category term='list of values'/><category term='free'/><category term='SQL Server'/><category term='CRUD generator'/><category term='&quot;Instructions on how to use a Mac&quot;'/><category term='Comments'/><category term='MediaWiki Personal Tools'/><category term='business intelligence'/><category term='Common Table Expression'/><category term='CreateUserWizard'/><category term='no svg'/><category term='data warehouse'/><category term='MediaWiki help files'/><category term='&quot;How to use a mac&quot;'/><category term='Regions'/><category term='Programming'/><category term='Failed to execute the request because the ASP.NET process identity does not have read permissions to the global assembly cache. Error: 0x80070005 Access'/><category term='ASP.NET'/><category term='Standard'/><category term='templates to edit'/><category term='Code'/><category term='SMTP'/><category term='It is an error to use a section registered as allowDefinition=&apos;MachineToApplication&apos; beyond application level'/><category term='humanized dates'/><category term='Business Objects'/><category term='Function'/><category term='script'/><category term='PC'/><category term='Roman numerals'/><category term='copying helpfiles'/><category term='SSIS'/><category term='Commenting'/><category term='Hierachies'/><category term='varchar(max)'/><category term='humanizing dates'/><category term='Entropia'/><category term='&quot;Macs suck&quot;'/><category term='Integration Services'/><category term='Nasty Errors'/><category term='Stupid user mistakes'/><category term='Windows Vista'/><category term='SendingMail'/><category term='MediaWiki'/><category term='Security tab missing'/><category term='TRUNCATE'/><category term='SQL Server 2005'/><category term='fixing images'/><category term='toolbar'/><category term='large value types'/><category term='command parameters'/><category term='.NET Framework'/><category term='CRUD'/><category term='&quot;Microsoft Mantra&quot;'/><category term='IIS'/><category term='config'/><category term='Dates'/><category term='PASS'/><category term='won'/><category term='Yay'/><category term='visual studio'/><category term='C#'/><category term='E-mail'/><category term='preventing data deletion'/><category term='max'/><category term='data types'/><category term='Collation'/><category term='CTE'/><category term='edit the mediawiki toolbar'/><category term='DELETE'/><category term='source code'/><category term='DROP TABLE'/><category term='date today'/><category term='date yesterday'/><category term='Data warehousing'/><category term='If Business Objects were... Business Objects'/><category term='T-SQL'/><category term='Add a tab to Personal Tools'/><category term='Windows boot manager'/><category term='.NET'/><category term='reusing'/><title type='text'>EntropiaOnline development</title><subtitle type='html'>This blog is intended to serve as a development blog for the site &lt;a href ="http://www.entropiaonline.com"&gt;http://www.entropiaonline.com&lt;/a&gt;. As the site progresses, we'll post code snippets and coding techniques of how we dealt with certain problems we ran into. Once the userbase starts growing, we'll also use this blog as a way to try and find out what the users would prefer seeing added next.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-8827696078232944222</id><published>2009-11-17T09:29:00.002+01:00</published><updated>2009-11-17T09:34:08.291+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='If Business Objects were... Business Objects'/><title type='text'>If Business Objects...</title><content type='html'>...was an actor, it would be Sylverster Stallone. It somehow looks slightly impressive with its sleeves rolled up. And then it opens its mouth...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-8827696078232944222?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/8827696078232944222/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=8827696078232944222' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/8827696078232944222'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/8827696078232944222'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2009/11/if-business-objects.html' title='If Business Objects...'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-7283593562095955700</id><published>2009-11-11T17:34:00.002+01:00</published><updated>2009-11-11T17:44:35.765+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MediaWiki'/><category scheme='http://www.blogger.com/atom/ns#' term='Add a tab to Personal Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='MediaWiki Personal Tools'/><title type='text'>MediaWiki - Add a tab to everyone's Personal Tools</title><content type='html'>For a while now, I had adding an extra option to the Personal Tools on my list of things to do. My wiki's main entry point for my users is through my forum (which has a user-bridge to the wiki, meaning it is not neccessary for my users to create seperate logins for the wiki if they already have an account on the forum), but I wanted to add a link back to the main site somewhere.&lt;br /&gt;&lt;br /&gt;The logo would have been my choice, but we use that for users to be able to return back to the main wiki-site. So I figured it would be nice to add this to the "Personal Tools" menu, which is the menu in the upper right corner that shows your username, "My talk", "My preferences", etc. &lt;br /&gt;&lt;br /&gt;Here's how to do it. In your includes folder, there's a file called SkinTemplate.php. Open that in an editor, and look for the following:&lt;br /&gt;&lt;br /&gt;[code]&lt;br /&gt;   $personal_urls['userpage'] = array(&lt;br /&gt;    'text' =&gt; $this-&gt;username,&lt;br /&gt;    'href' =&gt; &amp;$this-&gt;userpageUrlDetails['href'],&lt;br /&gt;    'class' =&gt; $this-&gt;userpageUrlDetails['exists']?false:'new',&lt;br /&gt;    'active' =&gt; ( $this-&gt;userpageUrlDetails['href'] == $pageurl )&lt;br /&gt;   );[/code]&lt;br /&gt;&lt;br /&gt;Directly above that, add the following:&lt;br /&gt;&lt;br /&gt;[code]&lt;br /&gt;   $personal_urls['myId'] = array(&lt;br /&gt;    'text' =&gt; 'myText',&lt;br /&gt;    'href' =&gt; 'myHref'&lt;br /&gt;   );[/code]&lt;br /&gt;&lt;br /&gt;myId is a unique identifier name for the personal url. &lt;br /&gt;myText is the name you want the link to have&lt;br /&gt;myHref is where the new link should point to.&lt;br /&gt;&lt;br /&gt;That's it. You're done. &lt;br /&gt;&lt;br /&gt;Note that the method above means the link will be the first link to appear. If you prefer setitng it somewhere inbetween instead, move the snippet of code to the proper location.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-7283593562095955700?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/7283593562095955700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=7283593562095955700' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/7283593562095955700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/7283593562095955700'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2009/11/mediawiki-add-tab-to-everyones-personal.html' title='MediaWiki - Add a tab to everyone&apos;s Personal Tools'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-6581612367785561023</id><published>2009-10-20T21:05:00.016+02:00</published><updated>2009-10-22T20:09:40.043+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MediaWiki'/><category scheme='http://www.blogger.com/atom/ns#' term='templates to edit'/><category scheme='http://www.blogger.com/atom/ns#' term='no svg'/><category scheme='http://www.blogger.com/atom/ns#' term='copying helpfiles'/><category scheme='http://www.blogger.com/atom/ns#' term='fixing images'/><category scheme='http://www.blogger.com/atom/ns#' term='MediaWiki help files'/><title type='text'>MediaWiki - Help file import, no SVG support, and additional edits</title><content type='html'>Another MediaWiki post. This time, I ran into some trouble after exporting all help pages from the official wiki, and trying to import them to my own, as described &lt;a href="http://www.mediawiki.org/wiki/Help:Copying"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'd also recommend you to import Manual:LocalSettings.php, as that is referenced in one of the help pages in an admin-only box. &lt;br /&gt;&lt;br /&gt;At the bottom of the list of files referenced, there's a whole bunch of images, which you have to save manually. Some include files in .svg format (vector based), but before you can actually use those, you need to install additional software. &lt;br /&gt;&lt;br /&gt;My problem is that I have no idea how to install stuff my VPN, as I am not sure my host enabled a shell account for me. So rather than potentially messing up my box, or relying on my host for something I'm not even sure will add that much value, I figured I'd learn something about wiki, and just change the references from .svg to the png format in which I saved all the files.&lt;br /&gt;&lt;br /&gt;As you see, the official wiki page is little help. "You might have to edit some pages to fix the link". &lt;br /&gt;&lt;br /&gt;Anyway, here's the pages/items that require editing for the images:&lt;br /&gt;&lt;br /&gt;Template:Admin_tip&lt;br /&gt;Template:PD_Help_Page (I also removed some conditional IF statement here)&lt;br /&gt;&lt;br /&gt;Further edits I did:&lt;br /&gt;All pages: Removed {{Languages}} tags.&lt;br /&gt;&lt;br /&gt;Help:Navigation - There's an admin-block halfway down the page that references a bunch of settings in the LocalSettings.php file. However, the link seemed broken. I replaced this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;{{mediawiki|Manual:LocalSettings.php#Upload location|upload location}} &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;with this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;[[Manual:LocalSettings.php#Upload location]]&lt;/blockquote&gt;, and the same for the other links in the block.&lt;br /&gt;&lt;br /&gt;Help:Starting_a_new_page - Similar edit to the one at Help:Navigation. In the admin-tip, replaced:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;{{mediawiki|Extension:Inputbox|inputbox extension}}&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;with &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;[[Extension:Inputbox|inputbox extension]]&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Help:Navigation references LocalSettings.php, which in turn references Template:Caution. Let's tackle that one next. First of all, we need the proper image referenced. The SVG is &lt;a href="http://www.mediawiki.org/wiki/File:Nuvola_apps_important.svg"&gt;here&lt;/a&gt;, from where you can also download the other formats. I picked sng. &lt;br /&gt;&lt;br /&gt;There's also some weird code in the template that I removed. I basically changed the whole top section, which checks the format of the template invocation, and stripped out the ability to use tables (for some reason, the conditional if made my template look all whack):&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;{{#if: {{{1|}}}|&lt;table cellspacing="0" cellpadding="0" border="0" style="background: transparent;"&gt;&lt;tr&gt;&lt;td nowrap="true" valign="top"&gt;}}[[Image:Nuvola apps important.svg|18px|Caution!]] '''Caution''': {{#if: {{{1|}}}|&lt;/td&gt;&lt;td valign="top"&gt;{{{1|}}}&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;}}&lt;noinclude&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;with:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;[[Image:Nuvola apps important.png|18px|Caution!]] '''Caution''': &lt;noinclude&gt; &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;More will follow soon :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-6581612367785561023?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/6581612367785561023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=6581612367785561023' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/6581612367785561023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/6581612367785561023'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2009/10/mediawiki-help-file-import-no-svg.html' title='MediaWiki - Help file import, no SVG support, and additional edits'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-425195206408434029</id><published>2009-10-20T18:52:00.003+02:00</published><updated>2009-10-20T19:06:22.765+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='edit the mediawiki toolbar'/><category scheme='http://www.blogger.com/atom/ns#' term='MediaWiki'/><category scheme='http://www.blogger.com/atom/ns#' term='wiki'/><category scheme='http://www.blogger.com/atom/ns#' term='toolbar'/><title type='text'>MediaWiki - Toolbar</title><content type='html'>Recently, we downloaded and installed MediaWiki. To our surprise, our of the box, the toolbar available when installing is lacking quite a few buttons that are standard available on wikipedia itself.&lt;br /&gt;&lt;br /&gt;The MediaWiki helpfiles are less than helpful, though they do contain a &lt;a href="http://www.mediawiki.org/wiki/Customizing_edit_toolbar"&gt;description on how to add a single (table) button&lt;/a&gt;. For those wanting to replicate the look of the actual wiki, here's the code for the remaining buttons. You'll need to make modifications to two files (make backups first):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/w/EditPage.php&lt;br /&gt;&lt;br /&gt;Find the following snippet:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;   ),&lt;br /&gt;   array(&lt;br /&gt;    'image'  =&gt; $wgLang-&gt;getImageFile('button-hr'),&lt;br /&gt;    'id'     =&gt; 'mw-editbutton-hr',&lt;br /&gt;    'open'   =&gt; "\n----\n",&lt;br /&gt;    'close'  =&gt; '',&lt;br /&gt;    'sample' =&gt; '',&lt;br /&gt;    'tip'    =&gt; wfMsg('hr_tip'),&lt;br /&gt;    'key'    =&gt; 'R'&lt;br /&gt;   )&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Below/after that, add the following:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;,&lt;br /&gt;   array(&lt;br /&gt;    'image'  =&gt; $wgLang-&gt;getImageFile('button-redirect'),&lt;br /&gt;    'id'     =&gt; 'mw-editbutton-redirect',&lt;br /&gt;    'open'   =&gt; '#REDIRECT [[',&lt;br /&gt;    'close'  =&gt; ']]',&lt;br /&gt;    'sample' =&gt; wfMsg('redirect_sample'),&lt;br /&gt;    'tip'    =&gt; wfMsg('redirect_tip'),&lt;br /&gt;    'key'    =&gt; 'V'&lt;br /&gt;   ),&lt;br /&gt;   array(&lt;br /&gt;    'image'  =&gt; $wgLang-&gt;getImageFile('button-strike'),&lt;br /&gt;    'id'     =&gt; 'mw-editbutton-strike',&lt;br /&gt;    'open'   =&gt; "&lt;s&gt;",&lt;br /&gt;    'close'  =&gt; "&lt;/s&gt;",&lt;br /&gt;    'sample' =&gt; wfMsg('strike_sample'),&lt;br /&gt;    'tip'    =&gt; wfMsg('strike_tip'),&lt;br /&gt;    'key'    =&gt; 'S'&lt;br /&gt;   ),&lt;br /&gt;   array(&lt;br /&gt;    'image'  =&gt; $wgLang-&gt;getImageFile('button-linebreak'),&lt;br /&gt;    'id'     =&gt; 'mw-editbutton-linebreak',&lt;br /&gt;    'open'   =&gt; "&lt;br /&gt;",&lt;br /&gt;    'close'  =&gt; "",&lt;br /&gt;    'sample' =&gt; '',&lt;br /&gt;    'tip'    =&gt; wfMsg('linebreak_tip'),&lt;br /&gt;    'key'    =&gt; 'BR'&lt;br /&gt;   ),&lt;br /&gt;   array(&lt;br /&gt;    'image'  =&gt; $wgLang-&gt;getImageFile('button-superscript'),&lt;br /&gt;    'id'     =&gt; 'mw-editbutton-superscript',&lt;br /&gt;    'open'   =&gt; "&lt;sup&gt;",&lt;br /&gt;    'close'  =&gt; "&lt;/sup&gt;",&lt;br /&gt;    'sample' =&gt; wfMsg('superscript_sample'),&lt;br /&gt;    'tip'    =&gt; wfMsg('superscript_tip'),&lt;br /&gt;    'key'    =&gt; 'I1'&lt;br /&gt;   ),&lt;br /&gt;   array(&lt;br /&gt;    'image'  =&gt; $wgLang-&gt;getImageFile('button-subscript'),&lt;br /&gt;    'id'     =&gt; 'mw-editbutton-subscript',&lt;br /&gt;    'open'   =&gt; "&lt;sub&gt;",&lt;br /&gt;    'close'  =&gt; "&lt;/sub&gt;",&lt;br /&gt;    'sample' =&gt; wfMsg('subscript_sample'),&lt;br /&gt;    'tip'    =&gt; wfMsg('subscript_tip'),&lt;br /&gt;    'key'    =&gt; 'I2'&lt;br /&gt;   ),&lt;br /&gt;   array(&lt;br /&gt;    'image'  =&gt; $wgLang-&gt;getImageFile('button-smalltext'),&lt;br /&gt;    'id'     =&gt; 'mw-editbutton-smalltext',&lt;br /&gt;    'open'   =&gt; "&lt;small&gt;",&lt;br /&gt;    'close'  =&gt; "&lt;/small&gt;",&lt;br /&gt;    'sample' =&gt; wfMsg('smalltext_sample'),&lt;br /&gt;    'tip'    =&gt; wfMsg('smalltext_tip'),&lt;br /&gt;    'key'    =&gt; 'J1'&lt;br /&gt;   ),&lt;br /&gt;   array(&lt;br /&gt;    'image'  =&gt; $wgLang-&gt;getImageFile('button-hidden'),&lt;br /&gt;    'id'     =&gt; 'mw-editbutton-hidden',&lt;br /&gt;    'open'   =&gt; "&lt;!--",&lt;br /&gt;    'close'  =&gt; "--&gt;",&lt;br /&gt;    'sample' =&gt; wfMsg('hidden_sample'),&lt;br /&gt;    'tip'    =&gt; wfMsg('hidden_tip'),&lt;br /&gt;    'key'    =&gt; 'HC'&lt;br /&gt;   ),&lt;br /&gt;   array(&lt;br /&gt;    'image'  =&gt; $wgLang-&gt;getImageFile('button-gallery'),&lt;br /&gt;    'id'     =&gt; 'mw-editbutton-gallery',&lt;br /&gt;    'open'   =&gt; "&lt;gallery&gt;",&lt;br /&gt;    'close'  =&gt; "&lt;/gallery&gt;",&lt;br /&gt;    'sample' =&gt; wfMsg('gallery_sample'),&lt;br /&gt;    'tip'    =&gt; wfMsg('gallery_tip'),&lt;br /&gt;    'key'    =&gt; 'HC'&lt;br /&gt;   ),&lt;br /&gt;   array(&lt;br /&gt;    'image'  =&gt; $wgLang-&gt;getImageFile('button-blockquote'),&lt;br /&gt;    'id'     =&gt; 'mw-editbutton-blockquote',&lt;br /&gt;    'open'   =&gt; "&lt;blockquote&gt;",&lt;br /&gt;    'close'  =&gt; "&lt;/blockquote&gt;",&lt;br /&gt;    'sample' =&gt; wfMsg('blockquote_sample'),&lt;br /&gt;    'tip'    =&gt; wfMsg('blockquote_tip'),&lt;br /&gt;    'key'    =&gt; 'B1'&lt;br /&gt;   ),&lt;br /&gt;   array(&lt;br /&gt;   'image' =&gt; $wgLang-&gt;getImageFile('button-table'),&lt;br /&gt;   'id' =&gt; 'mw-editbutton-table',&lt;br /&gt;   'open' =&gt; "{|",&lt;br /&gt;   'close' =&gt; "|}",&lt;br /&gt;   'sample' =&gt; 'class="wikitable sortable border=1 cellpadding=5"&lt;br /&gt;   |+ table name&lt;br /&gt;   |-&lt;br /&gt;   ! style="color:#AAB5BE;background-color:#24313F;" | header 1&lt;br /&gt;   ! style="color:#AAB5BE;background-color:#24313F;" | header 2&lt;br /&gt;   ! style="color:#AAB5BE;background-color:#24313F;" | header 3&lt;br /&gt;   |-&lt;br /&gt;   | style="color:#24313F;" | row 1, cell 1&lt;br /&gt;   | style="color:#24313F;" | row 1, cell 2&lt;br /&gt;   | style="color:#24313F;" | row 1, cell 3&lt;br /&gt;   |-&lt;br /&gt;   | style="color:#24313F;" | row 2, cell 1&lt;br /&gt;   | style="color:#24313F;" | row 2, cell 2&lt;br /&gt;   | style="color:#24313F;" | row 2, cell 3&lt;br /&gt;   ',&lt;br /&gt;   'tip' =&gt; wfMsg('table_tip'),&lt;br /&gt;   'key' =&gt; 'A'&lt;br /&gt;   ),&lt;br /&gt;   array(&lt;br /&gt;    'image'  =&gt; $wgLang-&gt;getImageFile('button-reference'),&lt;br /&gt;    'id'     =&gt; 'mw-editbutton-reference',&lt;br /&gt;    'open'   =&gt; "&lt;ref&gt;",&lt;br /&gt;    'close'  =&gt; "&lt;/ref&gt;",&lt;br /&gt;    'sample' =&gt; wfMsg('reference_sample'),&lt;br /&gt;    'tip'    =&gt; wfMsg('reference_tip'),&lt;br /&gt;    'key'    =&gt; 'R1'&lt;br /&gt;   )&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;For icons, refer to the link above, and find the link at the first option.&lt;br /&gt;&lt;br /&gt;Secondly, you need to edit /w/languages/messages/MessagesEn.php. This file will allow us to add both the path to the actual icons (which ought to be placed in /skins/common/images, by the way), and assign a tooltip text (which shows when you hover your mouse over a button) and a sample (which will be put as an example when you click the button. For instance, when you will click the strike-out button, this will show up: &lt;s&gt;Struck out text&lt;/s&gt;, and Struck out text is the sample).&lt;br /&gt;&lt;br /&gt;Find:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt; 'button-hr'       =&gt; 'button_hr.png',&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Below it, add:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt; 'button-table'    =&gt; 'button_table.png',&lt;br /&gt; 'button-redirect' =&gt; 'button_redirect.png',&lt;br /&gt; 'button-strike' =&gt; 'button_strike.png',&lt;br /&gt; 'button-superscript' =&gt; 'button_sup_letter.png',&lt;br /&gt; 'button-subscript' =&gt; 'button_sub_letter.png',&lt;br /&gt; 'button-linebreak' =&gt; 'button_linebreak.png',&lt;br /&gt; 'button-smalltext' =&gt; 'button_small_text.png',&lt;br /&gt; 'button-hidden' =&gt; 'button_hide_comment.png',&lt;br /&gt; 'button-gallery' =&gt; 'button_gallery.png',&lt;br /&gt; 'button-blockquote' =&gt; 'button_blockquote.png',&lt;br /&gt; 'button-reference' =&gt; 'button_reflink.png',&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Then find:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;'hr_tip'          =&gt; 'Horizontal line (use sparingly)',&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;And replace it with:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;'table_tip'    =&gt; 'Insert table (3 by 3)',&lt;br /&gt;'redirect_tip'    =&gt; 'Redirect',&lt;br /&gt;'redirect_sample' =&gt; 'Target page name',&lt;br /&gt;'strike_tip'     =&gt; 'Strike',&lt;br /&gt;'strike_sample'   =&gt; 'Strike-through text',&lt;br /&gt;'subscript_tip'     =&gt; 'Subscript text',&lt;br /&gt;'subscript_sample'   =&gt; 'Subscript text',&lt;br /&gt;'superscript_tip'     =&gt; 'Superscript text',&lt;br /&gt;'superscript_sample'   =&gt; 'Superscript text',&lt;br /&gt;'smalltext_tip'     =&gt; 'Small text',&lt;br /&gt;'smalltext_sample'   =&gt; 'Small text',&lt;br /&gt;'hidden_tip'     =&gt; 'Insert hidden comment',&lt;br /&gt;'hidden_sample'   =&gt; 'Comment',&lt;br /&gt;'gallery_sample' =&gt; 'Image:Example.jpg|Caption1 &lt;br /&gt;Image:Example.jpg|Caption2',&lt;br /&gt;'gallery_tip' =&gt; 'Insert a picture gallery',&lt;br /&gt;'blockquote_tip'     =&gt; 'Insert block of quoted text',&lt;br /&gt;'blockquote_sample'   =&gt; 'Block quote',&lt;br /&gt;'reference_tip'     =&gt; 'Insert a reference',&lt;br /&gt;'reference_sample'   =&gt; 'Insert footnote text here',&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;That's all there really is to it. Your toolbar now reflects the standard one at wiki.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-425195206408434029?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/425195206408434029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=425195206408434029' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/425195206408434029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/425195206408434029'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2009/10/mediawiki-toolbar.html' title='MediaWiki - Toolbar'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-479332421924534098</id><published>2009-08-19T20:11:00.002+02:00</published><updated>2009-08-19T20:13:28.759+02:00</updated><title type='text'>The ten IKEA commandments</title><content type='html'>Today, news reported that the bible is no longer the most published book on earth, but that it in fact has been outnumbered in number of copies by the IKEA catalogue.&lt;br /&gt;&lt;br /&gt;This calls for ten brand new commandments. The new ten IKEA commandments:&lt;br /&gt; &lt;br /&gt;1) Thou shalt not buy assembled furniture, nor shalt thy buy furniture elsewhere.&lt;br /&gt;2) Thou shalt always count thy screws before commencing assembly.&lt;br /&gt;3) Thou shalt eat Swedish meatballs while thy shoppeth.&lt;br /&gt;4) Thou shalt not cut ahead in line.&lt;br /&gt;5) Thou shalt praise the brilliance of the cam screw.&lt;br /&gt;6) Thou shalt be allowed to return thy damaged on delivery products.&lt;br /&gt;7) Thou shalt not expect to be given a time of delivery.&lt;br /&gt;8) Thou shalt make use of the children's playroom while thy shoppeth.&lt;br /&gt;9) Thou shalt secure thy furniture to the wall in order to avoid toppling, and thou cannot sue IKEA in case of non-compliance, neener, neener.&lt;br /&gt;10) The Allen Wrench shalt be the object of nightly worship.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-479332421924534098?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/479332421924534098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=479332421924534098' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/479332421924534098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/479332421924534098'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2009/08/ten-ikea-commandments.html' title='The ten IKEA commandments'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-4512575669108456690</id><published>2009-05-18T11:12:00.004+02:00</published><updated>2009-05-18T11:54:04.496+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Business Objects'/><category scheme='http://www.blogger.com/atom/ns#' term='data warehouse'/><category scheme='http://www.blogger.com/atom/ns#' term='business intelligence'/><title type='text'>To Business Objects or not to Business Objects?</title><content type='html'>Just out of curiosity. How do others consider Business Objects? My former company, and my current employer use it as a reporting tool on top of their data warehouse. Basically, between the database layer and the end-user, there resides a Business Objects universe that acts as a semantical layer translating database-objects into business entities, which allows endusers without any knowledge of SQL whatsoever to quickly generate their own reports.&lt;br /&gt;&lt;br /&gt;That's the theory behind it, anyway. In reality, expecially at my current employer, I have to develop the reports, even after the universe phase, because our client has all kinds of specifications for report layouts (that the Business Objects reporting suite was never intended to be used for, but the client already sold it to their client, and seeing THEY don't have to build it anyway, that's all fine and dandy). Add to that that the existing universe is plain unfit to be consumed by end-users, and I'm seriously wondering why on earth the company is paying top dollars every year for a product that greatly complicates even the most trivial tasks. &lt;br /&gt;&lt;br /&gt;I present to you the following theory I came to develop over my time of working with Business Objects: "A properly desgined data warehouse (meaning star schemas using dimensions that make sense to business users) has no need for a translational layer like Business Objects provides". In other words, a proper star-schema makes the universe part of the BI implementation redundant, which will lead to the Business Objects reporting suite becoming at best a limiting (not to mention expensive) engine for making the data look pretty.&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;My main complaints with Business Objects:&lt;br /&gt;&lt;br /&gt;* Pricing&lt;br /&gt;* An engine that greatly complicates even the most trivial tasks&lt;br /&gt;* Poor documentation and error messages&lt;br /&gt;* Reliability is horrible. More than once I experienced things "magically" dissappearing or changing. At first I dismissed these as incidents or failure on my part, but I managed to be able to "reproduce" these anomalies.&lt;br /&gt;* When you're working with a proper data warehouse, the universe layers adds extremely little value.&lt;br /&gt;&lt;br /&gt;I'd be interested in hearing other people's opinions.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-4512575669108456690?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/4512575669108456690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=4512575669108456690' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/4512575669108456690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/4512575669108456690'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2009/05/to-business-objects-or-not-to-business.html' title='To Business Objects or not to Business Objects?'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-4973372569418668750</id><published>2008-12-19T09:56:00.002+01:00</published><updated>2008-12-19T10:03:46.173+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Vista'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows boot manager'/><category scheme='http://www.blogger.com/atom/ns#' term='Vista'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows XP'/><title type='text'>Removing XP from Windows Boot Manager</title><content type='html'>The other day I figured I'd try installing XP on my Vista lappie. Unfortunately, I did not bother to read properly, and just went ahead and tried. Now one problem I have is that my DVD drive in the laptop has been wonky from the getgo. I also did not bother creating a second partition (d'oh). &lt;br /&gt;&lt;br /&gt;Anyway, after starting the installation and going through the initial setup steps, my laptop started showing a new screen called Windows Boot Manager which showed the new XP setup, and was for some reason using that as a default boot. The end result was constant blue screens.&lt;br /&gt;&lt;br /&gt;I eventually solved the problem by first having Vista display hidden folders and files, as well as OS files. Having done that, removing the XP entry is as simple as deleting the boot.ini file from the root folder of the drive. You can also remove the XP install folders called $WIN_NT$.~BT and $WIN_NT$.~LS.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-4973372569418668750?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/4973372569418668750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=4973372569418668750' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/4973372569418668750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/4973372569418668750'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2008/12/removing-xp-from-windows-boot-manager.html' title='Removing XP from Windows Boot Manager'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-4309213740574236799</id><published>2008-12-08T08:13:00.011+01:00</published><updated>2008-12-08T08:56:27.121+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Business Objects'/><category scheme='http://www.blogger.com/atom/ns#' term='All values'/><category scheme='http://www.blogger.com/atom/ns#' term='list of values'/><title type='text'>Business Objects - Custom entry to list of values</title><content type='html'>After recently having joined a new employer, I'll be blogging a bit more about Business Objects and some tricks and tips to get certain stuff done. &lt;br /&gt;&lt;br /&gt;Let's start with adding a custom entry to a list of values (lov). In this case, we want to give a user the ability to select &lt;All&gt; in order to select all the values in the lov. &lt;br /&gt;&lt;br /&gt;First we of course create the lov itself. In this case, Iøll show a mockup of a lov of clients that pulls data from a table created specifically for the purpose. Imagine that during the ETL process, a SELECT DISTINCT (ClientName) fills the table every night, in order to avoid having to do the SELECT every time an end-user retrieves an updated copy of the universe. It would look something like the following:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_8AEZ74bQ6U4/STzLyNwGf3I/AAAAAAAAABo/vsHyU0Vf_Tc/s1600-h/lov1.JPG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 169px;" src="http://1.bp.blogspot.com/_8AEZ74bQ6U4/STzLyNwGf3I/AAAAAAAAABo/vsHyU0Vf_Tc/s200/lov1.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5277316926916689778" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;br /&gt;With the list of values itself in place, we now create a new object that will contain a dummy string called &lt;All Clients&gt;. In Oracle, we can do this by referencing the SYS.DUAL table. Let's start by creating the value itself:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_8AEZ74bQ6U4/STzNNwZgPcI/AAAAAAAAABw/ELI4h8f4-qw/s1600-h/lov2.JPG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 169px;" src="http://2.bp.blogspot.com/_8AEZ74bQ6U4/STzNNwZgPcI/AAAAAAAAABw/ELI4h8f4-qw/s200/lov2.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5277318499585244610" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Add the SYS.DUAL tab le to the universe, and then proceed by clicking on the "Table" button. There, select sys.dual from the list of tables. This will ensure the object will parse properly. &lt;br /&gt;&lt;br /&gt;Now open the original list of values again, and select the "properties" tab. Supply a meaningful name for the list of values, and then click the "Edit" button. Here, we will add the newly created &lt;All Clients&gt; object to the existing list of values. Click on the "Combine Queries" button (circled) in order to add the extra object. You will notice a second tab called "Query 2" appearing. Delete the existing variable there, and select the &lt;All Clients&gt; object:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_8AEZ74bQ6U4/STzQrPhBbhI/AAAAAAAAAB4/7x6Yd36A0QA/s1600-h/lov3.JPG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 56px;" src="http://4.bp.blogspot.com/_8AEZ74bQ6U4/STzQrPhBbhI/AAAAAAAAAB4/7x6Yd36A0QA/s200/lov3.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5277322304689368594" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Click "OK" twice to return. At this stage, I usually choose to hide the &lt;All Clients&gt; object, as its only purpose is to enhance the list of values already there. It also is recommended to ensure that on the properties page of the &lt;All Clients&gt; object, you turn off "Associate a list of values". &lt;br /&gt;&lt;br /&gt;To finish up, create a filter prompting the user to select a value from the list of values. To this, we will add the option to also select &lt;All Clients&gt;. It would look something like the following (this does assume there is an object "Blog\Client" available, from which the value will be compared with the filter):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_8AEZ74bQ6U4/STzSkPpjzoI/AAAAAAAAACA/qkzcUotzL0s/s1600-h/lov4.JPG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 169px;" src="http://2.bp.blogspot.com/_8AEZ74bQ6U4/STzSkPpjzoI/AAAAAAAAACA/qkzcUotzL0s/s200/lov4.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5277324383489347202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This should do the trick. Please be aware that the screenshots contain mockups that have not been validated against a real database, and therefore they might be not neccessarily work 100%. If you find this is the case, please let me know, and I will try to do it over again, and ensure it works against the eFashion universe.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-4309213740574236799?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/4309213740574236799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=4309213740574236799' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/4309213740574236799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/4309213740574236799'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2008/12/business-objects-custom-entry-to-list.html' title='Business Objects - Custom entry to list of values'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_8AEZ74bQ6U4/STzLyNwGf3I/AAAAAAAAABo/vsHyU0Vf_Tc/s72-c/lov1.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-8551589404746961747</id><published>2008-06-09T19:31:00.005+02:00</published><updated>2008-06-09T19:44:50.648+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Nasty Errors'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Stupid user mistakes'/><category scheme='http://www.blogger.com/atom/ns#' term='Failed to execute the request because the ASP.NET process identity does not have read permissions to the global assembly cache. Error: 0x80070005 Access'/><title type='text'>Failed to execute the request because the ASP.NET process identity does not have read permissions to the global assembly cache. Error: 0x80070005</title><content type='html'>I started working on a new website yesterday, and this time, rather than starting it as a webpage, I figured I'd use the proper TheBeerHouse (TBH) approach, and actually create a blank project, and then add the website as an existing project to it.&lt;br /&gt;&lt;br /&gt;I referenced the other projects required for everything to run (a web captcha control and a CustomEvents project), renamed all the namespaces, and figured I'd be on my way.&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;But my trustworthy Internet Explorer decided to give me hell, and just showed a page with an error message in bold red:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;&lt;strong&gt;Server Application Unavailable&lt;br /&gt;&lt;br /&gt;The web application you are attempting to access on this web server is currently unavailable. Please hit the "Refresh" button in your web browser to retry your request.&lt;br /&gt;&lt;br /&gt;Administrator Note: An error message detailing the cause of this specific request failure can be found in the system event log of the web server. Please review this log entry to discover what caused this error to occur.&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The application log showed the following messages (abbreviated)&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Failed to initialize the AppDomain:/LM/W3SVC/1/Root/&lt;sitename&gt;&lt;br /&gt;&lt;br /&gt;Exception: System.IO.FileLoadException&lt;br /&gt;&lt;br /&gt;Message: Could not load file or assembly 'System.Web, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. Access is denied. &lt;/blockquote&gt;&lt;br /&gt;Followed by:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;Failed to execute the request because the ASP.NET process identity does not have read permissions to the global assembly cache. Error: 0x80070005 Access&lt;br /&gt;is denied.&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;And finally: &lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;br /&gt;aspnet_wp.exe (PID: 1924) stopped unexpectedly.&lt;/p&gt;&lt;/blockquote&gt;As it turns out, due to setting up the site as a project, ASP.NET doesn't automatically get its permissions assigned to the project &lt;span id="google-navclient-hilite" style="COLOR: black; BACKGROUND-COLOR: yellow"&gt;folder&lt;/span&gt;. Doing that manually solved the problem.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-8551589404746961747?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/8551589404746961747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=8551589404746961747' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/8551589404746961747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/8551589404746961747'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2008/06/failed-to-execute-request-because.html' title='Failed to execute the request because the ASP.NET process identity does not have read permissions to the global assembly cache. Error: 0x80070005'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-6144745838602430032</id><published>2008-06-09T19:23:00.003+02:00</published><updated>2008-06-09T19:27:29.675+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security tab missing'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows XP'/><title type='text'>Security tab missing in XP</title><content type='html'>I was troubleshooting an annoying problem on my PC when I ran into another annoying problem. Whenever I wanted to check access rights to a specific folder, there was no "Security" tab available. Kind of makes it hard to determine whether the account has the proper permissions.&lt;br /&gt;&lt;br /&gt;Here's how to solve it:&lt;br /&gt;&lt;br /&gt;1) Open up Windows Explorer.&lt;br /&gt;2) Tools -&gt; Folder Options -&gt; View&lt;br /&gt;3) All the way at the bottom of the listbox under "Advanced settings", ensure “Use simple file sharing (Recommended)” is not checked.&lt;br /&gt;4) Click OK, and check permissions at will.&lt;br /&gt;&lt;br /&gt;(I can see why simple file sharing is recommended by default, but some form of indication would have been nice).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-6144745838602430032?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/6144745838602430032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=6144745838602430032' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/6144745838602430032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/6144745838602430032'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2008/06/security-tab-missing-in-xp.html' title='Security tab missing in XP'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-6704017137601535933</id><published>2008-05-12T15:43:00.004+02:00</published><updated>2008-06-09T19:44:17.853+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data warehousing'/><category scheme='http://www.blogger.com/atom/ns#' term='Collation'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2005'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='CHECKSUM'/><title type='text'>Collation and CHECKSUM do not play together nicely.</title><content type='html'>If you work with data warehouses, like yours truly, most likely you’ve had to write code that checks your dimension tables for changes. Our usual approach is to pump the most recent copy of the table into a staging table, and then compare it to the latest version of the data.&lt;br /&gt;&lt;br /&gt;Roughly, the comparison would be something like:&lt;br /&gt;&lt;br /&gt;SELECT&lt;br /&gt;P.Column1&lt;br /&gt;, P.Coulmn2&lt;br /&gt;FROM&lt;br /&gt;ProductionTable P&lt;br /&gt;INNER JOIN StagingTable S ON P.PKID = S.PKID&lt;br /&gt;WHERE&lt;br /&gt;&lt;br /&gt;Followed by a piece of code where the individual columns are compared. There’s two methods that we use: A column by column comparison (WHERE P.Column1 != S.Column1 OR P.Column2 != S.Column2), or a CHECKSUM method, where a CHECKSUM is done over all the columns of the staging table, and compared against the CHECKSUM over all the columns of the production table (WHERE CHECKSUM(S.Column1, S.coulmn2) != CHECKSUM(P.Column1, P.Column2).&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;Today, when testing some new code, I found that even though the values in the two tables were identical (except for one column I excluded), and yet, SQL Server reported the checksums to be different. A bit more investigation revealed that the reason behind this was because of collation differences. For those of you who never heard of it (I didn’t until about a year ago, despite having worked with databases for 5+ years in numerous international organizations), here’s an excerpt from BOL (“Selecting collations”):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Collations specify the rules for how strings of character data are sorted and compared, based on the norms of particular languages and locales. For example, in an ORDER BY clause, an English speaker would expect the character string 'Chiapas' to come before 'Colima' in ascending order. But a Spanish speaker in Mexico might expect words beginning with 'Ch' to appear at the end of a list of words starting with 'C'. Collations dictate these kinds of sorting and comparison rules. The Latin_1 General collation will sort 'Chiapas' before 'Colima' in an ORDER BY ASC clause, while the Traditional_Spanish collation will sort 'Chiapas' after 'Colima'.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Now the source system we pull our data from has a default collation of US-English, and our warehouse system uses Norwegian/Danish. Essentially, this means whenever we try and run comparison checks or updates between staging and production, we have to add a COLLATE DATABASE_DEFAULT clause in order to “convert” one set of values to another. That this also was an issue with CHECKSUM never occurred to me.&lt;br /&gt;&lt;br /&gt;Here’s some sample code to prove my point. We create a test table with two different collations, and insert identical values into them. First, we’ll run a SELECT to see the CHECKSUMs are different, a second select which does a collation conversion on the US-column, and finally a statement that boxes the “other” collation column to the proper one for the database, which will result in an identical CHECKSUM. The code was run on a database with a US collation, by the way:&lt;br /&gt;&lt;br /&gt;CREATE TABLE dbo.CHECKSUM_TEST&lt;br /&gt;(&lt;br /&gt;US nchar(10) NULL,&lt;br /&gt;DK nchar(10) COLLATE Danish_Norwegian_BIN NULL&lt;br /&gt;) ON [PRIMARY]&lt;br /&gt;&lt;br /&gt;INSERT INTO CHECKSUM_TEST&lt;br /&gt;(US, DK)&lt;br /&gt;VALUES ('foo', 'foo')&lt;br /&gt;&lt;br /&gt;INSERT INTO CHECKSUM_TEST&lt;br /&gt;(US, DK)&lt;br /&gt;VALUES&lt;br /&gt;('bar', 'bar')&lt;br /&gt;&lt;br /&gt;SELECT US, DK, CHECKSUM(US), CHECKSUM(DK)&lt;br /&gt;FROM CHECKSUM_TEST&lt;br /&gt;&lt;br /&gt;SELECT US, DK, CHECKSUM(US), CHECKSUM(DK COLLATE DATABASE_DEFAULT)&lt;br /&gt;FROM CHECKSUM_TEST&lt;br /&gt;&lt;br /&gt;DROP TABLE CHECKSUM_TEST&lt;br /&gt;&lt;br /&gt;I’ve deliberately used Unicode rather than non-Unicode for the columns, to prove that doesn’t really help to deal with this particular issue. Below are the results from the three statements:&lt;br /&gt;&lt;br /&gt;US DK&lt;br /&gt;---------- ---------- ----------- -----------&lt;br /&gt;foo foo 59294611 24735&lt;br /&gt;bar bar -2088615046 25698&lt;br /&gt;&lt;br /&gt;(2 row(s) affected)&lt;br /&gt;&lt;br /&gt;US DK&lt;br /&gt;---------- ---------- ----------- -----------&lt;br /&gt;foo foo 59294611 24735&lt;br /&gt;bar bar -2088615046 25698&lt;br /&gt;&lt;br /&gt;(2 row(s) affected)&lt;br /&gt;&lt;br /&gt;US DK&lt;br /&gt;---------- ---------- ----------- -----------&lt;br /&gt;foo foo 59294611 59294611&lt;br /&gt;bar bar -2088615046 -2088615046&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The lesson learnt here is to be careful when using CHECKSUM in combination with mixed collations, and when you do, it’s important to use the COLLATE statement on the proper column ;)&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-6704017137601535933?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/6704017137601535933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=6704017137601535933' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/6704017137601535933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/6704017137601535933'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2008/05/collation-and-checksum-do-not-play.html' title='Collation and CHECKSUM do not play together nicely.'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-3349958531506062714</id><published>2008-02-01T12:50:00.000+01:00</published><updated>2008-02-01T12:53:38.720+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='&quot;Instructions on how to use a Mac&quot;'/><category scheme='http://www.blogger.com/atom/ns#' term='&quot;Microsoft Mantra&quot;'/><category scheme='http://www.blogger.com/atom/ns#' term='PC'/><category scheme='http://www.blogger.com/atom/ns#' term='&quot;Macs suck&quot;'/><category scheme='http://www.blogger.com/atom/ns#' term='&quot;How to use a mac&quot;'/><title type='text'>How to use a Mac</title><content type='html'>Instructions on how to use a Mac:&lt;br /&gt;&lt;br /&gt;1) Unplug Mac from any electrical input. &lt;br /&gt;2) Get 1 gallon of water. Personally, I find water from the toilet works fine. If you're environmentally friendly, or your name is Al Gore, rainwater is the way to go.&lt;br /&gt;3) Pour the  water into any crevice in the Mac you can find.&lt;br /&gt;4) Take a 5 minute break while surfing www.microsoft.com and chanting "WINDOWS, WINDOWS, WINDOWS".&lt;br /&gt;5) Find a heavy object. Anvils, bowling balls, Oprah, whatever. Tie heavy object to the Mac.&lt;br /&gt;6) Open the window. If the number of your floor is less than 5, take the stairs up, or find another building.&lt;br /&gt;7) Drop Mac out of the window onto concrete underground (best results achieved when no potential passerby's are between Mac and concrete when gravity does its wonderful work).&lt;br /&gt;8) Grab sledgehammer and go outside. &lt;br /&gt;9) Until no pieces of the Mac are bigger than 1 square centimeter, bring down sledgehammer onto Mac.&lt;br /&gt;10) You're done! Now go back inside, buy a REAL computer, and read Bill Gates' memoires.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-3349958531506062714?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/3349958531506062714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=3349958531506062714' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/3349958531506062714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/3349958531506062714'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2008/02/how-to-use-mac.html' title='How to use a Mac'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-9050337452568567620</id><published>2008-01-17T08:49:00.001+01:00</published><updated>2008-01-17T08:54:50.721+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='source code'/><title type='text'>.NET Framework source code available!</title><content type='html'>Granted, this has little to do with developing the website (something that I've been slacking in for a bit now), but it's just damn cool.&lt;br /&gt;&lt;br /&gt;Scott Guthrie posted a note yesterday that the source code of the .NET Framework Libraries is available now. This means you can actually debug the Microsoft .NET classes!&lt;br /&gt;&lt;br /&gt;In the comments he also mentions that a downloadable version will be made available as well, which ensures you don't have to be online to see the source.&lt;br /&gt;&lt;br /&gt;Very cool. Read more on Scott's blog &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/16/net-framework-library-source-code-now-available.aspx"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-9050337452568567620?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/9050337452568567620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=9050337452568567620' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/9050337452568567620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/9050337452568567620'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2008/01/net-source-code-available.html' title='.NET Framework source code available!'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-1925761211741993289</id><published>2008-01-14T09:16:00.001+01:00</published><updated>2008-01-14T09:32:16.743+01:00</updated><title type='text'>[w] - Waiting for</title><content type='html'>How often doesn't it happen that you find yourself digging through your mail in order to see if there's anything you initiated, but for which you are dependant on others?&lt;br /&gt;&lt;br /&gt;If you're chaotic like me, that happens quite a lot. Often I'll have tried setting things in motion, only to find out later that nothing happened so far. Usually this means I'll have to waste quite a bit of time digging through my mail in order to see when I sent the mail, to who, and whether anything happened.&lt;br /&gt;&lt;br /&gt;This morning I came across an easy tip that will possibly save me all that time. In short, you create a new Outlook folder, and a rule that checks your outgoing mails. Should your mail contain a [w] tag, it will automatically be moved to your newly created folder, and you'll have a very easy way to have all items that require interaction from others listed together in a single spot.&lt;br /&gt;&lt;br /&gt;Find out more on &lt;a href="http://waiting-for.com/"&gt;http://waiting-for.com/&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-1925761211741993289?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/1925761211741993289/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=1925761211741993289' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/1925761211741993289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/1925761211741993289'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2008/01/w-waiting-for.html' title='[w] - Waiting for'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-8020202372187912710</id><published>2008-01-04T11:07:00.000+01:00</published><updated>2008-01-04T11:13:52.451+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='large value types'/><category scheme='http://www.blogger.com/atom/ns#' term='data types'/><category scheme='http://www.blogger.com/atom/ns#' term='varchar(max)'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2005'/><category scheme='http://www.blogger.com/atom/ns#' term='max'/><title type='text'>SQL Server 2005 varchar(max) in C#</title><content type='html'>An interesting question at work today: How to properly define a parameter that's varchar(max) in Sql Server 2005 from within C#?&lt;br /&gt;&lt;br /&gt;Sure, it should be possible to use the signature without adding the integer value. But what if a custom DataAdapter is being used that &lt;em&gt;does&lt;/em&gt; require a value if you supply a string? We could use 4000 as a value, but that kind of defeats the purpose of using the new datatype. 8000 then? Same difference; you still possibly end up with truncated strings. Should we make it 2bn? That's 2GB of memory. Not really an otpion in my book.&lt;br /&gt;&lt;br /&gt;After some googling, we found the answer: the size of the parameter should be set to -1. There's an example &lt;a href="http://msdn2.microsoft.com/en-us/library/a1904w6t(VS.80).aspx"&gt;here&lt;/a&gt;, where the -1 value is not explained in detail, but just shown in the code. We tested, and it works like a charm.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-8020202372187912710?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/8020202372187912710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=8020202372187912710' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/8020202372187912710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/8020202372187912710'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2008/01/sql-server-2005-varcharmax-in-c.html' title='SQL Server 2005 varchar(max) in C#'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-4604835740086059801</id><published>2007-10-24T16:01:00.000+02:00</published><updated>2007-10-24T17:11:31.862+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='humanizing dates'/><category scheme='http://www.blogger.com/atom/ns#' term='date yesterday'/><category scheme='http://www.blogger.com/atom/ns#' term='date today'/><category scheme='http://www.blogger.com/atom/ns#' term='date last week'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Dates'/><category scheme='http://www.blogger.com/atom/ns#' term='humanized dates'/><title type='text'>Humanized dates in C#</title><content type='html'>I've been looking for a way to make dates in the Forum sections of the site more user-friendly. Did some googling on how to accomplish this in either SQL or C#, but somehow that came up completely blank.&lt;br /&gt;&lt;br /&gt;I did manage to find some scripts for some stuff I never heard about, and &lt;a href="http://www.blake8086.com/blog/2007/06/12/humanize-date-javascript-to-emulate-outlooks-date-grouping/"&gt;1 javascript file&lt;/a&gt;. Just my luck. I &lt;em&gt;seriously&lt;/em&gt; dislike javascript. Maxxim from the &lt;a href="http://p2p.wrox.com/forum.asp?FORUM_ID=261"&gt;wrox forum &lt;/a&gt;will most likely be chuckling now, since he's been advising me to brush up my skills in Javascript ;)&lt;br /&gt;&lt;br /&gt;So here's the translation in C#. Since I'm not sure about the copyright notice, I'll just slap a copy of the original in:&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;/**&lt;br /&gt;* C# translation: Copyright (c) 2007 Peter Schmitz&lt;br /&gt;* &lt;a href="http://entropia-online.blogspot.com/"&gt;http://entropia-online.blogspot.com&lt;/a&gt;&lt;br /&gt;*&lt;br /&gt;* Original Javascript code: Copyright (c) 2007 Blake Householder&lt;br /&gt;* &lt;a href="http://www.blake8086.com/"&gt;http://www.blake8086.com/&lt;/a&gt;&lt;br /&gt;*&lt;br /&gt;* Permission is hereby granted, free of charge, to any person&lt;br /&gt;* obtaining a copy of this software and associated documentation&lt;br /&gt;* files (the "Software"), to deal in the Software without&lt;br /&gt;* restriction, including without limitation the rights to use, copy,&lt;br /&gt;* modify, merge, publish, distribute, sublicense, and/or sell copies&lt;br /&gt;* of the Software, and to permit persons to whom the Software is&lt;br /&gt;* furnished to do so, subject to the following conditions:&lt;br /&gt;*&lt;br /&gt;* The above copyright notice and this permission notice shall be&lt;br /&gt;* included in all copies or substantial portions of the Software.&lt;br /&gt;*&lt;br /&gt;* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,&lt;br /&gt;* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF&lt;br /&gt;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND&lt;br /&gt;* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS&lt;br /&gt;* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN&lt;br /&gt;* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN&lt;br /&gt;* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE&lt;br /&gt;* SOFTWARE.&lt;br /&gt;*&lt;br /&gt;*&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;public string HumanizeDate(DateTime date)&lt;br /&gt;{&lt;br /&gt;DateTime dateNow = DateTime.Now;&lt;br /&gt;&lt;br /&gt;// Determine the start of the date's week&lt;br /&gt;DateTime startOfWeek = (date.Date - TimeSpan.FromDays((double)date.DayOfWeek));&lt;br /&gt;&lt;br /&gt;// We'll use this variable for monthly comparison&lt;br /&gt;int intMonthCompare = ((date.Year * 12 + date.Month) - (dateNow.Year * 12 + dateNow.Month));&lt;br /&gt;&lt;br /&gt;// Do the monthly comparison first, as that's the biggest possible way to group&lt;br /&gt;if (intMonthCompare &gt; 1)&lt;br /&gt;{&lt;br /&gt;return "Beyond next month";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (intMonthCompare &lt; -1) &lt;br /&gt;{&lt;br /&gt;return "Older";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (intMonthCompare == 1)&lt;br /&gt;{&lt;br /&gt;return "Next month";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (intMonthCompare == -1)&lt;br /&gt;{&lt;br /&gt;return "Last month";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Now do the same, but in weeks&lt;br /&gt;TimeSpan ts = (startOfWeek - dateNow.Date);&lt;br /&gt;if (ts.Days &gt; 28)&lt;br /&gt;{&lt;br /&gt;return "Five weeks from now";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (ts.Days &gt; 21)&lt;br /&gt;{&lt;br /&gt;return "Four weeks from now";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (ts.Days &gt; 14)&lt;br /&gt;{&lt;br /&gt;return "Three weeks from now";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (ts.Days &gt; 7)&lt;br /&gt;{&lt;br /&gt;return "Two weeks from now";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (ts.Days &gt; 0)&lt;br /&gt;{&lt;br /&gt;return "Next week";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (ts.Days &lt; -35)&lt;br /&gt;{&lt;br /&gt;return "Five weeks ago";&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;if (ts.Days &lt; -28)&lt;br /&gt;{&lt;br /&gt;return "Four weeks ago";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (ts.Days &lt; -21)&lt;br /&gt;{&lt;br /&gt;return "Three weeks ago";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (ts.Days &lt; -14)&lt;br /&gt;{&lt;br /&gt;return "Two weeks ago";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (ts.Days &lt; -7)&lt;br /&gt;{&lt;br /&gt;return "Last week";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Nothing found so far. Let's see if it's tomorrow, today, or yesterday&lt;br /&gt;ts = date.Date - dateNow.Date;&lt;br /&gt;&lt;br /&gt;if (ts.Days == 1)&lt;br /&gt;{&lt;br /&gt;return "Tomorrow";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (ts.Days == 0)&lt;br /&gt;{&lt;br /&gt;return "Today";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (ts.Days == -1)&lt;br /&gt;{&lt;br /&gt;return "Yesterday";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Still nothing? Must be a different day in this week then&lt;br /&gt;return date.DayOfWeek.ToString();&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-4604835740086059801?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/4604835740086059801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=4604835740086059801' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/4604835740086059801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/4604835740086059801'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/10/humanized-dates-in-c.html' title='Humanized dates in C#'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-4914337672332295318</id><published>2007-10-07T12:56:00.000+02:00</published><updated>2007-10-07T13:05:45.417+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visual studio'/><category scheme='http://www.blogger.com/atom/ns#' term='It is an error to use a section registered as allowDefinition=&apos;MachineToApplication&apos; beyond application level'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='config'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>A strange error...</title><content type='html'>It's been a while since my last post. That is mostly due to trying to actually get the website as a whole working.&lt;br /&gt;&lt;br /&gt;We planned on going beta last weekend, but illness and distractions (in the form of LOTRO) put a stop to that.&lt;br /&gt;&lt;br /&gt;To top things off, I've been worrying about the forums. Our potential members are used to the vBulletin forums, and the current TBH forums are nothing even remotely like it. Heck, there's no subforums, and not even the ability to send one another private messages. In itself, that shouldn't be too hard to implement, but one also should take into account that just building it is not going to cut it.&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;The end-user will also demand to actually use the functionality, and vBulletin has all that conveniently located.&lt;br /&gt;&lt;br /&gt;So for now, I'm undecided where to go. I downloaded a free forum coded in C# yesterday, courtesy of Frans Bouma, that I will give our beta users to test. I also can try just buying vBulleting, and then writing code to integrate the users from my site into the forum databases (which is mySql). As a third alternative, I can try and code things myself, and see if other TBH users are interested as well in adding functionality.&lt;br /&gt;&lt;br /&gt;Time will tell.&lt;br /&gt;&lt;br /&gt;In the meantime, I came across a particular error today:&lt;br /&gt;&lt;br /&gt;"Error 110 It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS. C:\...\EntropiaOnline\forumsbck\web.config 56 "&lt;br /&gt;&lt;br /&gt;Never seen it before, but what happened is that yesterday I changed some code. In order to ensure I'd not lose anything, before I overwrote the code on the actual site, I grabbed the code I was going to replace, and put it in a local subfolder of my website.&lt;br /&gt;&lt;br /&gt;Due to there being a web.config file in it as well, I started getting the error. The solution was to remove the newly created folder from the project-folder. The error is caused by having duplicate web.configs in subfolders, that are not "registered" in Visual Studio (by registered, I mean you did not add the folder itself to the project).&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-4914337672332295318?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/4914337672332295318/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=4914337672332295318' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/4914337672332295318'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/4914337672332295318'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/10/strange-error.html' title='A strange error...'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-3837313315282436990</id><published>2007-09-10T20:55:00.000+02:00</published><updated>2007-09-11T18:17:35.168+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='reusing'/><category scheme='http://www.blogger.com/atom/ns#' term='command parameters'/><title type='text'>Reusing command parameters</title><content type='html'>A while ago, at that hobby I practise during the day (some call it work. I resent that. Work is what I do when I come home), I was writing a piece of VB.NET code (I know... I know...) that would fire off a bunch of stored procedures, all with the exact same parameters.&lt;br /&gt;&lt;br /&gt;So I wondered if I really had to define the parameters once for every time I called the procedures, or whether I could actually just change the CommandText.&lt;br /&gt;&lt;br /&gt;I created a little test app, and went away. Today, I rewrote the code to C#, and decided to put it up here, in order to show that reusing command parameters is perfectly legal in .NET (and to me, it actually sounds logical too, as it prevents the coder from having to rewrite the same code over and over again).&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;I created a page with one single button, and two labels (I left their names unchanged, as I was doing this during worktime, and I wanted to have the test take as little time as possible.&lt;br /&gt;&lt;br /&gt;I added the code, with a few comments thrown in for clarity, and used the labels to post the ID's of the first records I got back from my stored procedures.&lt;br /&gt;&lt;br /&gt;Next I fired off the code, while keeping an eye on my profiler, and sure enough, both the stored procedures were executed. I then changed the code a little and increased the value for the second stored procedure, in order to see if that would still work. It did:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_8AEZ74bQ6U4/RuWhktREZ4I/AAAAAAAAABA/mwrYe5H4Q64/s1600-h/Profiler.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5108667004320245634" style="CURSOR: hand" alt="" src="http://2.bp.blogspot.com/_8AEZ74bQ6U4/RuWhktREZ4I/AAAAAAAAABA/mwrYe5H4Q64/s200/Profiler.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Click &lt;a href="http://groups.google.com/group/entropiaonline/web/ReusingCommandParameters.zip"&gt;here&lt;/a&gt; to download the sample project and test it for yourself. The project assumes you have the &lt;a href="http://www.codeplex.com/MSFTDBProdSamples/Release/ProjectReleases.aspx?ReleaseId=4004"&gt;Adventureworks database&lt;/a&gt; installed. you will have to create the two stored procedures usp_Test1, and usp_Test2 as well (they're also included in the ZIP file).&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-3837313315282436990?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/3837313315282436990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=3837313315282436990' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/3837313315282436990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/3837313315282436990'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/09/reusing-command-parameters.html' title='Reusing command parameters'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_8AEZ74bQ6U4/RuWhktREZ4I/AAAAAAAAABA/mwrYe5H4Q64/s72-c/Profiler.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-1073007311193746735</id><published>2007-09-05T20:51:00.000+02:00</published><updated>2007-09-05T21:01:11.678+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CRUD'/><category scheme='http://www.blogger.com/atom/ns#' term='Yay'/><category scheme='http://www.blogger.com/atom/ns#' term='PASS'/><category scheme='http://www.blogger.com/atom/ns#' term='won'/><title type='text'>I won something...</title><content type='html'>After I finished up my &lt;a href="http://entropia-online.blogspot.com/2007/08/free-script-to-create-crud-procedures.html"&gt;CRUD script&lt;/a&gt;, I submitted it to a competition I stumbled upon while reading up at &lt;a href="http://www.sql-server-performance.com/"&gt;www.sql-server-performance.com&lt;/a&gt;. Mostly in the hope of trying to gain some attention for the script. Besides, when do I ever win anything?&lt;br /&gt;&lt;br /&gt;Well, this time I did! I just received an E-mail stating I won a full-conference pass to the &lt;a href="https://www.sqlpass.org/"&gt;PASS summit&lt;/a&gt; in Denver, Colorado.&lt;br /&gt;&lt;br /&gt;I won't be able to attend, but I definitely am proud at the moment :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-1073007311193746735?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/1073007311193746735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=1073007311193746735' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/1073007311193746735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/1073007311193746735'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/09/i-won-something.html' title='I won something...'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-2846495853945152107</id><published>2007-09-05T20:13:00.000+02:00</published><updated>2007-09-05T20:51:37.432+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SendingMail'/><category scheme='http://www.blogger.com/atom/ns#' term='CreateUserWizard'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><title type='text'>CreateUserWizard - SendingMail event</title><content type='html'>After following the examples in the book, I figured I wanted to add some extra functionality to the Membership and UserProfiling section.&lt;br /&gt;&lt;br /&gt;While it allows your users to signup smoothly and simply, using a CreateUserWizard, I wanted to add an option where my site sends the user a link with a GUID embedded in it, in order to verify that the user didn't only fill in a properly formatted E-mail address, but actually does own the mail address that was entered.&lt;br /&gt;&lt;br /&gt;I went off on my merry way, using a code snippet from my local installation of MSDN as a basis:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;e.Message.Body.Replace("&lt;%PasswordQuestion%&gt;", Createuserwizard1.Question);&lt;br /&gt;e.Message.Body.Replace("&lt;%PasswordAnswer%&gt;", Createuserwizard1.Answer);&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;So my code became:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;protected void SendMail(object sender, MailMessageEventArgs e)&lt;br /&gt;{&lt;br /&gt;// Generate a GUID&lt;br /&gt;string guidResult = System.Guid.NewGuid().ToString();&lt;br /&gt;&lt;br /&gt;// Code to paste into a URL, which I cannot paste cause Blogger throws a fit.&lt;br /&gt;&lt;br /&gt;e.Message.IsBodyHtml = true;&lt;br /&gt;e.Message.Body.Replace("&lt;%Link%&gt;", url);&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;After running the code, nothing happened. I set a breakpoint and tried again. Nothing. I commented out several options that the book carried as extra steps that I thought might interfere. Still nothing.&lt;br /&gt;&lt;br /&gt;I then tried hooking the UserCreated event to the SendMail event that I defined, but ran into trouble when trying to create EmailEventargs to pass as a parameter.&lt;br /&gt;&lt;br /&gt;And luckily, then I googled on "CreateUserWizard MailMessageEventArgs", and came across &lt;a href="http://blogs.sqlxml.org/bryantlikes/archive/2005/12/14/4571.aspx"&gt;Bryant's blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The last line of code now reads:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;e.Message.Body = e.Message.Body.Replace("&lt;%Link%&gt;", url);&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;And lo and behold, problem solved, and I find a neat link included in my mail :)&lt;br /&gt;&lt;br /&gt;Bryant, I owe you a beer!&lt;br /&gt;&lt;br /&gt;And to those still unconvinced by the Internet, I predict that some day it will be a big hit!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-2846495853945152107?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/2846495853945152107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=2846495853945152107' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/2846495853945152107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/2846495853945152107'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/09/createuserwizard-sendingmail-event.html' title='CreateUserWizard - SendingMail event'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-2046032300373285693</id><published>2007-09-03T21:19:00.000+02:00</published><updated>2007-09-03T21:43:57.877+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SMTP'/><category scheme='http://www.blogger.com/atom/ns#' term='IIS'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='E-mail'/><title type='text'>E-mailing from ASP.NET</title><content type='html'>I've been working on a website for a while now. As a base, I use the book &lt;a href="http://www.amazon.com/gp/product/0764584642?ie=UTF8&amp;tag=entropi09-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0764584642"&gt;ASP.NET 2.0 Website Programming: Problem - Design - Solution (Programmer to Programmer)&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=entropi09-20&amp;l=as2&amp;o=1&amp;a=0764584642" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;. Now using that, you actually add code to have E-mail sent from within your application using SMTP.&lt;br /&gt;&lt;br /&gt;However, I couldn't get it to work. My E-mail address seemed valid enough, as did the code in my web.config:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_8AEZ74bQ6U4/RtxjSfeBPaI/AAAAAAAAAA4/wQsll5flZyQ/s1600-h/SMTPSettings.JPG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_8AEZ74bQ6U4/RtxjSfeBPaI/AAAAAAAAAA4/wQsll5flZyQ/s200/SMTPSettings.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5106065246867504546" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Since I was planning on adding a new feature to the existing code to E-mail a new member a link they have to click before having their account activated, it seemed like a good idea to first sort out the whole mail thing.&lt;br /&gt;&lt;br /&gt;I fiddled with a few things, but kept getting a: "5.7.1 Unable to relay for &lt;mailaddress&gt;" error.&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;The solution is laughably simple (thankfully). Go to Internet Information Services (under Administrative Tools), expand your IIS server, and select right-click the Default virtual SMTP server. Select Properties, and go to the Access tab.&lt;br /&gt;&lt;br /&gt;Under the "Relay restrictions" section, click the "relay" button. There, ensure the "Only the list below" option is selected, and press the "Add" button.&lt;br /&gt;&lt;br /&gt;Under "Single computer", fill in 127.0.0.1, and click OK. That's it!&lt;br /&gt;&lt;br /&gt;For security's sake, I chose to uncheck the checkbox named "Allow all computers which succesfully authenticate to relay".&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-2046032300373285693?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/2046032300373285693/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=2046032300373285693' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/2046032300373285693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/2046032300373285693'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/09/e-mailing-from-aspnet.html' title='E-mailing from ASP.NET'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_8AEZ74bQ6U4/RtxjSfeBPaI/AAAAAAAAAA4/wQsll5flZyQ/s72-c/SMTPSettings.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-1955594116835818940</id><published>2007-08-29T19:07:00.000+02:00</published><updated>2007-09-02T15:52:22.342+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='free'/><category scheme='http://www.blogger.com/atom/ns#' term='CRUD'/><category scheme='http://www.blogger.com/atom/ns#' term='CRUD generator'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><title type='text'>A free script to create CRUD procedures.</title><content type='html'>Recently, both at my job, as well as while working on the site, I found myself having to write countless CRUD stored procedures in order to facilitate retrieving and storing data in my tables. The majority of these reflected an exact replication of the database table model (i.e. updating all columns), and I found writing those stored procedures to be a real burden. It was boring, repetitive and error prone work (especially the UPDATE procedures, where one has to replicate columns three times (once as input variables (which includes data types), once as columnnames, and once again as variables (but this time without the columnnames).&lt;br /&gt; &lt;br /&gt;Being the lazy guy I am, I decided I would automate the matter, and write a script to automatically create the procedures for me. Before I started, I decided I would make a few starting assumptions:&lt;br /&gt; &lt;br /&gt;1) I wanted the SELECT procedure to be able to accept either an ID-number or a Name (assuming that like me, you called the column something involving '%Name') for an individual row, or neither, in which case the whole table should be returned.&lt;br /&gt;2) I wanted to be able to have the DELETE procedures to be optional. I achieved this by using a bit-flag and IF statements to see if it ought to be created or not.&lt;br /&gt;3) I wanted the user to be able to specify certain columns to exclude. In the database I'm working on for the site, there are numerous audit columns to keep track of when data is entered or modified, and by who. Naturally, this is not required in all of the procedures, so I wanted a mechanism for the end-user to include or exclude these columns.&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt; &lt;br /&gt;The result of my work is the script below. I've briefly tested the generated procedures against my own database, and there, they work like a charm. Perhaps others who run more specialised or customised databases will be able to come up with unexpected errors etc. If so, please do let me know.&lt;br /&gt; &lt;br /&gt;Of course, the script will not cover 100% of anybody's specific wishes. In fact, I'm quite sure that some of the procedures will need to be customised to suit your needs, but you will find this script will enable you to start with at least some foundation in place. &lt;br /&gt; &lt;br /&gt;I'm releasing this script under the &lt;a href="http://creativecommons.org/licenses/by-nc-nd/3.0/"&gt;Creative Commons Attribution Non-Commercial No Derivatives&lt;/a&gt; license, which means you are free to download and share the script, provided you mention and link back to me. However, you are not allowed to change or commercially use the script. I might change this to a less restrictive license in the future, however for now, I want to be able to evaluate comments etc first. This is the first time I ever released anything under a license, so any comments regarding that are more than welcome.&lt;br /&gt; &lt;br /&gt;A list of things I have figured I could enhance the script with:&lt;br /&gt; &lt;br /&gt;1) Add error handling to the stored procedures.&lt;br /&gt;2) Add support for schemas in SQL Server 2005.&lt;br /&gt;3) Add paging support to the select procedures, by adding two additional parameters.&lt;br /&gt; &lt;br /&gt;Also, I might later on decide to automatically generate .NET custom classes based on the exact database tables. &lt;br /&gt;&lt;br /&gt;Click &lt;a href="http://entropiaonline.googlegroups.com/web/Create%20CRUD%20Procedures.sql?gda=6G1EMEsAAAB8ivrd2UTWjc1nG_hleETTAflpEi3mOMpEKfhOgoauEGG1qiJ7UbTIup-M2XPURDSmypVlqno4_it2N9lTpWGiitur_uebucBYfqxllU7_mQ&amp;hl=en"&gt;here&lt;/a&gt; to download the script.&lt;br /&gt;&lt;br /&gt;One last comment, should you decide to alter the generated stored procedures to suit your specific needs, do remember to rename the new procedure. The script will automatically drop its standard procedures, in order to always reflect the latest table schemas. &lt;br /&gt;&lt;br /&gt;&lt;a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/"&gt;&lt;br /&gt;&lt;img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-nd/3.0/88x31.png" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This work is licensed under a &lt;br /&gt;&lt;a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/"&gt;Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 License&lt;/a&gt;.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-1955594116835818940?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/1955594116835818940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=1955594116835818940' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/1955594116835818940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/1955594116835818940'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/08/free-script-to-create-crud-procedures.html' title='A free script to create CRUD procedures.'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-7106129908979796088</id><published>2007-08-28T19:36:00.000+02:00</published><updated>2007-08-28T21:07:11.984+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='T-SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2005'/><category scheme='http://www.blogger.com/atom/ns#' term='Hierachies'/><category scheme='http://www.blogger.com/atom/ns#' term='CTE'/><category scheme='http://www.blogger.com/atom/ns#' term='Common Table Expression'/><title type='text'>Hierarchical data with Common Table Expressions</title><content type='html'>Today, I finally managed to crack a problem that's been bothering me for some time. Some weeks ago I started working on the database schema that the site will be using, and the Entropia auction system gave me some trouble.&lt;br /&gt;&lt;br /&gt;You see, the auction in the game is built up hierarchically, and I eventually want to show individual items in the database under the auction section they belong to (as with a lot of items, it's unclear exacty where to find them).&lt;br /&gt;&lt;br /&gt;That in itself was easy enough, but not if you want to store the data in third normal form, but at the same time want to use some form of a cookie-trail, so the user will know exactly where to go. (With cookie-trail I mean something along the lines of "Items \ Tools \ Misc Tools"). I chose to store my data in a table with an AuctionCategoryID, AuctionCategoryName, and an AuctionCategoryParentID, the latter of which represents a SELF-JOIN.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_8AEZ74bQ6U4/RtRjJ_eBPZI/AAAAAAAAAAw/oRdkOeHCzEk/s1600-h/AuctionCategoriesSelfJoin.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5103813301024931218" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://3.bp.blogspot.com/_8AEZ74bQ6U4/RtRjJ_eBPZI/AAAAAAAAAAw/oRdkOeHCzEk/s200/AuctionCategoriesSelfJoin.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;(The figure above doesn't actually represent my own table. I chose to give the very bottom nodes of the tree a ParentID of -1, and did not define -1 as an AuctionCategoryID. Hence, creating a Foreign Key is just not possible. The figure is just for clarification).&lt;br /&gt;&lt;br /&gt;I first tried meddling with code a bit myself, but found that my code just didn't do the trick. Sure, I could hard-code a number of self-joins, but what if suddenly more categories were added? I'd have to alter my function. That was definitely not an option.&lt;br /&gt;&lt;br /&gt;I tried a few more things, but found my code was not robust enough, and that there were sorting troubles (among other things).&lt;br /&gt;&lt;br /&gt;I Googled a bit, and initially ended up with a solution like &lt;a href="http://www.vbmysql.com/articles/database-design/managing-hierarchical-data-in-mysql/"&gt;this&lt;/a&gt; (Joe Celko describes a similar method in his "SQL for Smarties"). Hardly elegant, and hardly dynamic (although it would be possible, of course, to ensure there would be a difference of a few numbers between each of the individual "nodes". However, that still potentially means I could run out of space, and would then have to manually alter stuff again. Not an option if you ask me).&lt;br /&gt;&lt;br /&gt;Enter the recursive Common Table Expression. BOL doesn't seem very helpful, but hopefully the code below will make things easier to see.&lt;br /&gt;&lt;br /&gt;The first query within the Common Table Expression defines the root level. As you see, the -1 value I mentioned above is hard-coded. The UNION ALL is the key to ensuring the self-join will work for an indefinte number of child nodes. The second query just fills in those child nodes.&lt;br /&gt;&lt;br /&gt;Note that it is possible to potentially create an infinite loop, though CTEs also offer a way to cap this.&lt;br /&gt;&lt;br /&gt;The code:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WITH&lt;/span&gt; AuctionPath&lt;span style="color:#006600;"&gt; -- The name of the CTE&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;[Name]&lt;br /&gt;, [AuctionCategoryID]&lt;br /&gt;, [Path]&lt;br /&gt;, [Level]&lt;br /&gt;)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt;&lt;br /&gt;AuctionCategoryName &lt;span style="color:#006600;"&gt;-- Name&lt;br /&gt;&lt;/span&gt;, AuctionCategoryID&lt;span style="color:#006600;"&gt; -- AuctionCategoryID&lt;/span&gt;&lt;br /&gt;, &lt;span style="color:#cc33cc;"&gt;CONVERT&lt;/span&gt;(&lt;span style="color:#3333ff;"&gt;varchar&lt;/span&gt;(255), AuctionCategoryName)&lt;span style="color:#006600;"&gt; -- Path&lt;br /&gt;&lt;/span&gt;, 1 &lt;span style="color:#006600;"&gt;-- Level&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;AuctionCategories&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WHERE&lt;/span&gt;&lt;br /&gt;AuctionCategoryParentID = -1 &lt;span style="color:#006600;"&gt;-- Only the parent nodes here&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;UNION ALL&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt;&lt;br /&gt;AuctionCategoryName &lt;span style="color:#006600;"&gt;-- Name&lt;br /&gt;&lt;/span&gt;, AuctionCategories.AuctionCategoryID &lt;span style="color:#006600;"&gt;-- AuctionCategoryID&lt;/span&gt;&lt;br /&gt;, &lt;span style="color:#cc33cc;"&gt;CONVERT&lt;/span&gt;(&lt;span style="color:#3333ff;"&gt;varchar&lt;/span&gt;(255), Path + &lt;span style="color:#ff0000;"&gt;' \ '&lt;/span&gt; + AuctionCategoryName) &lt;span style="color:#006600;"&gt;-- Path&lt;br /&gt;&lt;/span&gt;, [Level] + 1&lt;span style="color:#006600;"&gt; -- Level&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;AuctionCategories&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;INNER JOIN&lt;/span&gt; AuctionPath &lt;span style="color:#3333ff;"&gt;ON&lt;/span&gt; AuctionCategories.AuctionCategoryParentID = AuctionPath.[AuctionCategoryID]&lt;br /&gt;)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt;&lt;br /&gt;[Name]&lt;br /&gt;, [AuctionCategoryID]&lt;br /&gt;, [Path]&lt;br /&gt;, [Level]&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;AuctionPath&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ORDER BY&lt;/span&gt; AuctionCategoryID&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;OPTION&lt;/span&gt; (&lt;span style="color:#3333ff;"&gt;MAXRECURSION&lt;/span&gt; 5); &lt;span style="color:#006600;"&gt;-- The maximum amount of recursions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Some things of note. There are certain conditions to recursive CTEs. From BOL:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The number of columns in the anchor and recursive members must be the same.&lt;/li&gt;&lt;li&gt;The data type of a column in the recursive member must be the same as the&lt;br /&gt;data type of the corresponding column in the anchor member.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In the quoted text, anchor is what I have refered to as root node, and recursive member is a child node.&lt;/p&gt;&lt;p&gt;I hope this helps a little if you're facing a situation where you need to do hierarchies. Once you manage to get the trick, there's nothing to it, really :)&lt;/p&gt;&lt;p&gt;Many thanks to both Kalman Toth and russellb over at the &lt;a href="http://sqlforums.windowsitpro.com/web/forum/messageview.aspx?catid=74&amp;threadid=86652&amp;amp;enterthread=y"&gt;sqlmag forums&lt;/a&gt;.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-7106129908979796088?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/7106129908979796088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=7106129908979796088' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/7106129908979796088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/7106129908979796088'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/08/hierarchical-data-with-common-table.html' title='Hierarchical data with Common Table Expressions'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_8AEZ74bQ6U4/RtRjJ_eBPZI/AAAAAAAAAAw/oRdkOeHCzEk/s72-c/AuctionCategoriesSelfJoin.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-3588399240622960854</id><published>2007-08-26T11:44:00.000+02:00</published><updated>2007-08-27T09:55:51.150+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Roman numerals'/><category scheme='http://www.blogger.com/atom/ns#' term='Function'/><category scheme='http://www.blogger.com/atom/ns#' term='T-SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Entropia'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Roman numerals</title><content type='html'>If you play Entropia Universe (formerly Project Entropia), you're probably aware that mining depositsizes have two distinctive identifiers. The first being the name of the claimsize (i.e. tiny, very poor, poor, all the way to Immense). However, those terms do not clearly indicate which of the two is larger.&lt;br /&gt;&lt;br /&gt;In the case of very poor vs. poor, it's obvious, but is Significant bigger or smaller than Substantial? In order to avoid that kind of confusion, MindArk also decided to give claims a &lt;a href="http://en.wikipedia.org/wiki/Roman_numerals"&gt;Roman numeral&lt;/a&gt; indication.&lt;br /&gt;&lt;br /&gt;I order to have the database reflect these numerals, I decided to create a function that will translate our number system into Roman numerals. It works surprisingly easy, actually. The function takes an input parameter, which is the number to be translated.&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;br /&gt;It then determines the regular numbers, the tens, the hundreds, and the thousands, and translates those into their Roman counterparts using a case statement. When it encounters a 4 or a 9 (which, obviously, are the special numbers because they are not a simple repetitive sequence of characters), it will translate those as well.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;CREATE FUNCTION&lt;/span&gt; [dbo].[fn_ToRoman]&lt;br /&gt;(&lt;br /&gt;@InputNumber &lt;span style="color:#3333ff;"&gt;INT&lt;/span&gt;&lt;br /&gt;)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;RETURNS VARCHAR&lt;/span&gt;(16)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;AS&lt;br /&gt;BEGIN&lt;br /&gt;DECLARE&lt;br /&gt;&lt;/span&gt;@Singles &lt;span style="color:#3333ff;"&gt;INT&lt;/span&gt;&lt;br /&gt;, @Tens &lt;span style="color:#3333ff;"&gt;INT&lt;/span&gt;&lt;br /&gt;, @Hundreds &lt;span style="color:#3333ff;"&gt;INT&lt;/span&gt;&lt;br /&gt;, @Thousands &lt;span style="color:#3333ff;"&gt;INT&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt;&lt;br /&gt;@Singles = @InputNumber%10&lt;br /&gt;, @Tens = @InputNumber%100/10&lt;br /&gt;, @Hundreds = @InputNumber%1000/100&lt;br /&gt;, @Thousands = @InputNumber%10000/1000&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;RETURN&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;REPLICATE&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'M'&lt;/span&gt;, @Thousands) +&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;CASE&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WHEN&lt;/span&gt; @Hundreds &lt;span style="color:#3333ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;REPLICATE&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'C'&lt;/span&gt;, @Hundreds) &lt;span style="color:#3333ff;"&gt;WHEN&lt;/span&gt; @Hundreds = 4 &lt;span style="color:#3333ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;'CD'&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;WHEN&lt;/span&gt; @Hundreds = 9 &lt;span style="color:#3333ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;'CM' &lt;/span&gt;&lt;span style="color:#3333ff;"&gt;WHEN&lt;/span&gt; @Hundreds &gt;= 5 &lt;span style="color:#3333ff;"&gt;THEN&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; 'D'&lt;/span&gt; +&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;REPLICATE&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'C'&lt;/span&gt;, @Hundreds - 5)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ELSE&lt;/span&gt; ''&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;END&lt;/span&gt; +&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;CASE&lt;br /&gt;WHEN&lt;/span&gt; @Tens &lt;span style="color:#3333ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;REPLICATE&lt;/span&gt;('&lt;span style="color:#ff0000;"&gt;X'&lt;/span&gt;, @Tens) &lt;span style="color:#3333ff;"&gt;WHEN&lt;/span&gt; @Tens = 4 &lt;span style="color:#3333ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;'XL'&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;WHEN&lt;/span&gt; @Tens = 9 &lt;span style="color:#3333ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;'XC' &lt;/span&gt;&lt;span style="color:#3333ff;"&gt;WHEN&lt;/span&gt; @Tens &gt;= 5 &lt;span style="color:#3333ff;"&gt;THEN&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; 'L'&lt;/span&gt; + &lt;span style="color:#cc33cc;"&gt;REPLICATE&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'X',&lt;/span&gt; @Tens - 5)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ELSE&lt;/span&gt; ''&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;END&lt;/span&gt; +&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;&lt;span style="color:#3333ff;"&gt;CASE&lt;/span&gt;&lt;br /&gt;WHEN&lt;/span&gt; @Singles &lt;span style="color:#3333ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;REPLICATE&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'I'&lt;/span&gt;,@Singles) &lt;span style="color:#3333ff;"&gt;WHEN&lt;/span&gt; @Singles = 4 &lt;span style="color:#3333ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;'IV'&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;WHEN&lt;/span&gt; @Singles = 9 &lt;span style="color:#3333ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;'IX' &lt;/span&gt;&lt;span style="color:#3333ff;"&gt;WHEN&lt;/span&gt; @Singles &gt;=5 &lt;span style="color:#3333ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;'V'&lt;/span&gt; + &lt;span style="color:#cc33cc;"&gt;REPLICATE&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'I'&lt;/span&gt;,@Singles-5)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ELSE&lt;/span&gt; ''&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;END&lt;/span&gt;&lt;br /&gt;)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;END&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-3588399240622960854?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/3588399240622960854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=3588399240622960854' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/3588399240622960854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/3588399240622960854'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/08/roman-numerals.html' title='Roman numerals'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-3409917811070267962</id><published>2007-08-19T12:07:00.000+02:00</published><updated>2007-08-27T11:29:55.710+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Regions'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>Yes! Code regions in SQL :)</title><content type='html'>Currently I'm working on a long long long SQL script that automatically writes CRUD (Create, Read, Update, Delete) procedures based on a table's definition. If you are like me, you will find that you group certain code together.&lt;br /&gt;&lt;br /&gt;In Visual Studio, you can conveniently wrap #region tags around the code, so you can just collapse the region when you know certain stuff works, and doesn't need to be edited anymore. Not so in SQL Query Analyzer (or SQL Server Management Studio for that matter).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.sqlvisualizer.com/"&gt;SQL Visualizer&lt;/a&gt; does offer that option though. You start a region with a -- REGION comment, and end with -- END REGION.&lt;br /&gt;Because it works with comment blocks, your code will work anywhere. Except within this tool, you will be able to now use regions:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_8AEZ74bQ6U4/RsgYX_eBPYI/AAAAAAAAAAo/OkmSojlIJU4/s1600-h/SQLRegion.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5100353378450488706" style="MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://3.bp.blogspot.com/_8AEZ74bQ6U4/RsgYX_eBPYI/AAAAAAAAAAo/OkmSojlIJU4/s200/SQLRegion.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I've used other SQL tools before, and quickly found myself abandoning them due to being, well frankly, crap. I'll have to work with this one a bit more before I can actually judge it properly, but regions in SQL code are definitely something I miss in the Microsoft environment.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;Update 08/27/2007:&lt;/span&gt; I've decided to not use SQL Analyzer a lot, unless it's for developing large scripts like the CRUD script I mentioned before. Reason is that it's not possible to copy/paste output messages (which, if you're building dynamic SQL scripts, is kind of neccessary to test).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-3409917811070267962?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.sqlvisualizer.com/' title='Yes! Code regions in SQL :)'/><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/3409917811070267962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=3409917811070267962' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/3409917811070267962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/3409917811070267962'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/08/yes-code-regions-in-sql.html' title='Yes! Code regions in SQL :)'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_8AEZ74bQ6U4/RsgYX_eBPYI/AAAAAAAAAAo/OkmSojlIJU4/s72-c/SQLRegion.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-4791354933435675195</id><published>2007-08-15T10:49:00.000+02:00</published><updated>2007-08-15T10:51:47.017+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSIS'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2005'/><category scheme='http://www.blogger.com/atom/ns#' term='Integration Services'/><title type='text'>SSIS - DataReader issue</title><content type='html'>Just a quick note, unrelated to anything to do with the actual website.&lt;br /&gt; &lt;br /&gt;Today, at work, I was working on a task that involves moving data from a production database to a Historic database. The production environment has been misused at times in the past, and as a result, there's numerous backups of tables residing in the database.&lt;br /&gt; &lt;br /&gt;Due to regulations, just dropping the tables or wiping data is not an option. Hence, we chose to move it to the historic database. Now to accomplish this, I selected SSIS as our prefered tool. Stupidly enough, I chose to use ADO.NET as a data connection. The fun started when I was creating the actual "Data Flow" objects. I must have created a dozen of them when suddenly I was confronted with an error that SSIS was unable to translate from unicode to non-unicode data.&lt;br /&gt; &lt;br /&gt;Huh?&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt; &lt;br /&gt;I checked my CREATE TABLE scripts, and sure enough, the data types in both source and destination were set to char. I tried altering the Source's External columns, which seemed to work from the colum's properties, but actually didn't if you would check the datatype coming into the Source. I tried fiddling with the Source's Output column, but got an error message that I was not allowed to. I tried explicitly casting the column as char in the Source's SELECT statement. No luck. &lt;br /&gt; &lt;br /&gt;A colleague came over and suggested using a Dereived Column object. Again, that didn't work. I ended up Googling, and came to an MSDN link. There, it stated somewhere halfway the page:&lt;br /&gt; &lt;br /&gt;"One issue when using ADO.NET is that there is no ADO.NET data type corresponding to VARCHAR (non-Unicode character) in relational databases. Therefore, ADO.NET data sources output all character data as Unicode. This can cause problems with simple components that use ADO.NET sources and destinations that expect single-byte character types. You can work around this by using a Data Conversion transformation."&lt;br /&gt; &lt;br /&gt;I tested this, and using a Data Conversion did indeed work. But what a lot of extra work to do something relatively simple. I decided to just switch all connections to OLEDB.&lt;br /&gt; &lt;br /&gt;Conclusion: When dealing with non-unicode char columns, OLEDB might be the better choice.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-4791354933435675195?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/4791354933435675195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=4791354933435675195' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/4791354933435675195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/4791354933435675195'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/08/ssis-datareader-issue.html' title='SSIS - DataReader issue'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-3390695487412299538</id><published>2007-08-10T17:20:00.000+02:00</published><updated>2007-08-11T10:17:20.894+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Standard'/><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Comments'/><category scheme='http://www.blogger.com/atom/ns#' term='Commenting'/><title type='text'>Moan: Commenting while programming</title><content type='html'>Att: Microsoft, Oracle, Sun&lt;br /&gt;CC: WWC, Google (they're in on anything, so why not CC them? At the very least they'll get a chuckle out of it)&lt;br /&gt;&lt;br /&gt;Subject: Programming comments&lt;br /&gt;&lt;br /&gt;Dear Sirs/Madams,&lt;br /&gt;&lt;br /&gt;If you can find some time in your undoubtedly busy schedules, would it be possible for you to discuss a universal combination of characters to note a line or block of text within code as comment, please?&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;As a programmer, I love commenting my code. It makes it easy for me to identify what bits of code do, to indicate why I used a certain approach, and my peers will get the same benefits. All in all, comments are our friends.&lt;br /&gt;&lt;br /&gt;However, I have never understood the reason for having numerous ways to define comments. For instance, see the following snippets:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Visual Basic:&lt;br /&gt;&lt;span style="color:#009900;"&gt;' This is a comment. Start the line with an apostrophe.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;C# / Java:&lt;br /&gt;&lt;span style="color:#009900;"&gt;// This is a comment.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;SQL / C# / Java / Oracle:&lt;br /&gt;&lt;span style="color:#009900;"&gt;/* This is a comment block */&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;SQ: / Oracle:&lt;br /&gt;&lt;span style="color:#009900;"&gt;-- This is a comment&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;HTML:&lt;br /&gt;&lt;span style="color:#009900;"&gt;&amp;#60&amp;#37 -- This is a comment -- &amp;#37&amp;#62&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Etc.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Could it be arranged so that there is one standard approach that works in every language? It would make things so much easier for those of us who regularly switch between languages/flavours.&lt;br /&gt;&lt;br /&gt;Kthanks.&lt;br /&gt;&lt;br /&gt;My next moan will demand we get the exact same syntax, too ;)&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-3390695487412299538?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/3390695487412299538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=3390695487412299538' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/3390695487412299538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/3390695487412299538'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/08/moan-commenting-while-programming.html' title='Moan: Commenting while programming'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-5296359673309996287</id><published>2007-08-10T10:05:00.000+02:00</published><updated>2007-08-11T10:16:21.360+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='preventing data deletion'/><category scheme='http://www.blogger.com/atom/ns#' term='DROP TABLE'/><category scheme='http://www.blogger.com/atom/ns#' term='DELETE'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='TRUNCATE'/><title type='text'>Preventing accidental data deletion in SQL Server</title><content type='html'>After a few hours of working on the proper table definition for your base table, and filling it with data, you sit back, and decide to do some minor maintenance on a few other tables. You truncate a table, and seconds later realise to your horror that you just purged the table you spent quite some time on filling.&lt;br /&gt;&lt;br /&gt;Sound familiar?&lt;br /&gt;&lt;br /&gt;It recently happened to me, and I decided to put some mechanisms in place to prevent accidental deletion of data. Of course the best way to prevent accidental deletion is by making sure you are always 100% awake, and you simply do not make errors. Unfortunately that is unrealistic, so I have a few tips to help out.&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;As a very basic and rather obvious tip, I'll advise you to just make a database backup every time you spent a lot of time on filling in basetables. Now for some added technical tricks:&lt;br /&gt;&lt;br /&gt;1) To prevent accidental deletion of data, I decided to use INSTEAD OF triggers. BOL again:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;INSTEAD OF&lt;br /&gt;Specifies that &lt;em&gt;the DML trigger is executed instead of the triggering SQL statement&lt;/em&gt;, therefore, overriding the actions of the triggering statements. INSTEAD OF cannot be specified for DDL triggers.&lt;br /&gt;&lt;br /&gt;At most, one INSTEAD OF trigger per INSERT, UPDATE, or DELETE statement can be defined on a table or view. However, you can define views on views where each view has its own INSTEAD OF trigger.&lt;br /&gt;&lt;br /&gt;INSTEAD OF triggers are not allowed on updatable views that use WITH CHECK OPTION. SQL Server raises an error when an INSTEAD OF trigger is added to an updatable view WITH CHECK OPTION specified. The user must remove that option by using ALTER VIEW before defining the INSTEAD OF trigger.&lt;br /&gt;&lt;br /&gt;{ [ DELETE ] [ , ] [ INSERT ] [ , ] [ UPDATE ] }&lt;br /&gt;Specifies the data modification statements that activate the DML trigger when it is tried against this table or view. At least one option must be specified. Any combination of these options in any order is allowed in the trigger definition.&lt;br /&gt;&lt;br /&gt;For INSTEAD OF triggers, the DELETE option is not allowed on tables that have a referential relationship specifying a cascade action ON DELETE. Similarly, the UPDATE option is not allowed on tables that have a referential relationship specifying a cascade action ON UPDATE.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The definition of my trigger is similar to this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;CREATE TRIGGER&lt;/span&gt; DeleteTable_1 &lt;span style="color:#3333ff;"&gt;ON&lt;/span&gt; Table_1&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;INSTEAD OF DELETE&lt;br /&gt;AS&lt;br /&gt;BEGIN&lt;br /&gt;     IF&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;@@rowcount&lt;/span&gt; &gt; 0&lt;br /&gt;     &lt;span style="color:#3333ff;"&gt;BEGIN&lt;br /&gt;          RAISERROR&lt;/span&gt;( '&lt;span style="color:#ff0000;"&gt;Rows in Table_1 cannot be deleted!&lt;/span&gt;', 16, 2 )&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;          ROLLBACK&lt;br /&gt;     END&lt;br /&gt;END&lt;/span&gt;&lt;span style="color:#3366ff;"&gt;&lt;br /&gt;&lt;/span&gt;GO&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;When I now try to delete rows (using &lt;span style="color:#3333ff;"&gt;DELETE FROM&lt;/span&gt; Table_1), I will see the following errors in my Query result:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;Msg 50000, Level 16, State 2, Procedure DeleteTable_1, Line 7&lt;br /&gt;Rows in Table_1 cannot be deleted!&lt;br /&gt;Msg 3609, Level 16, State 1, Line 1&lt;br /&gt;The transaction ended in the trigger. The batch has been aborted.&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately, that does NOT prevent the table from being Truncated.&lt;br /&gt;&lt;br /&gt;2) To avoid accidently dropping a table, I create views over them and use the option WITH SCHEMABINDING. From Bol (my emphasis):&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;SCHEMABINDING&lt;br /&gt;Binds the view to the schema of the underlying table or tables. &lt;em&gt;When SCHEMABINDING is specified, the base table or tables cannot be modified in a way that would affect the view definition.&lt;/em&gt; The view definition itself must first be modified or dropped to remove dependencies on the table that is to be modified. When you use SCHEMABINDING, the select_statement must include the two-part names (schema.object) of tables, views, or user-defined functions that are referenced. All referenced objects must be in the same database.&lt;br /&gt;&lt;br /&gt;Views or tables that participate in a view created with the SCHEMABINDING clause cannot be dropped unless that view is dropped or changed so that it no longer has schema binding. Otherwise, the Microsoft SQL Server 2005 Database Engine raises an error. &lt;em&gt;Also, executing ALTER TABLE statements on tables that participate in views that have schema binding fail when these statements affect the view definition&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;SCHEMABINDING cannot be specified if the view contains alias data type columns."&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The first bit I emphasised clearly shows that using views in this way is a neat little feature to prevent accidental drops of a table.&lt;br /&gt;&lt;br /&gt;The second quote is IMHO also important, as it shows that clearly the table should be "final". If you later on decide that the table in fact needs extra (or less) columns, the VIEW will actually make your life harder.&lt;br /&gt;&lt;br /&gt;As an extra tip, when you create a view to use WITH SCHEMABINDING, always use the fully qualified name of the table (i.e. dbo.Salaries instead of just Salaries). Also, you cannot use *, but instead you will have to define all the columns in the query statement.&lt;br /&gt;&lt;br /&gt;Nice, but still no protection against a TRUNCATE.&lt;br /&gt;&lt;br /&gt;3) In fact, the only way to prevent TRUNCATE from executing on your table is to ensure there is a Foreign Key relationship to the table. If you are (like me) still working on the tables that will eventually link to the base table, you can always create a dummy table that references your base table:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;CREATE TABLE&lt;/span&gt; [dbo].[Table_2]&lt;br /&gt;(&lt;br /&gt;     [TableID] [int] NULL,&lt;br /&gt;     [Table_1ID] [int] NULL&lt;br /&gt;)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ON&lt;/span&gt; [PRIMARY]&lt;br /&gt;&lt;br /&gt;GO&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ALTER TABLE&lt;/span&gt; [dbo].[Table_2]&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WITH CHECK&lt;br /&gt;ADD CONSTRAINT&lt;/span&gt; [FK_Table_2_Table_1] &lt;span style="color:#3333ff;"&gt;FOREIGN KEY&lt;/span&gt;([Table_1ID])&lt;br /&gt;REFERENCES [dbo].[Table_1] ([TableID])&lt;br /&gt;GO&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ALTER TABLE&lt;/span&gt; [dbo].[Table_2] &lt;span style="color:#3333ff;"&gt;CHECK CONSTRAINT&lt;/span&gt; [FK_Table_2_Table_1]&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Now when you try to TRUNCATE Table_1, you will receive the following error:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;Msg 4712, Level 16, State 1, Line 1&lt;br /&gt;Cannot truncate table 'TABLE_1' because it is being referenced by a FOREIGN KEY constraint.&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;&lt;/p&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Well, that concludes this post. I hope you will find it helpful in preventing you from accidentally destroying some of your hard work. Of course all comments are welcome :)&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-5296359673309996287?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/5296359673309996287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=5296359673309996287' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/5296359673309996287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/5296359673309996287'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/08/preventing-accidental-data-deletion.html' title='Preventing accidental data deletion in SQL Server'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6400137361122596109.post-1915171618231572577</id><published>2007-07-30T22:59:00.000+02:00</published><updated>2007-08-03T18:21:48.864+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EntropiaOnline'/><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='SQL Server 2005'/><category scheme='http://www.blogger.com/atom/ns#' term='Entropia'/><title type='text'>Welcome!</title><content type='html'>Hi there,&lt;br /&gt;&lt;br /&gt;We'd like to take the time to welcome you to the official developer blog of &lt;a href="http://www.entropiaonline.com/"&gt;http://www.entropiaonline.com/&lt;/a&gt;. This blog will be mostly used to describe some pieces of code that we found to be tremendously helpful while developing the site, discussion of programming techniques, and as a way for us to get feedback from our users as to what they would like us to work on next.&lt;br /&gt;&lt;br /&gt;As some initial information, the techniques we will be using include ASP.NET (2.0), SQL Server 2005, and C#. Once we feel the content of the site is to our liking, we will most likely also look into AJAX to enhance the user experience.&lt;br /&gt;&lt;br /&gt;Thanks for stopping by!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6400137361122596109-1915171618231572577?l=entropia-online.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://entropia-online.blogspot.com/feeds/1915171618231572577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6400137361122596109&amp;postID=1915171618231572577' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/1915171618231572577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6400137361122596109/posts/default/1915171618231572577'/><link rel='alternate' type='text/html' href='http://entropia-online.blogspot.com/2007/07/welcome.html' title='Welcome!'/><author><name>Peter Schmitz</name><uri>http://www.blogger.com/profile/17105493071717932752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp3.blogger.com/_8AEZ74bQ6U4/RrNUdX6hAVI/AAAAAAAAAAg/2_xK3jSI4nQ/s200/VildernessGirls.jpg'/></author><thr:total>0</thr:total></entry></feed>
