SQL Server Database Corruption

I’m currently studying for the 70-450 exam to obtain my MCITP in SQL Server Database Administration. I wanted to get a better understanding for SQL Server’s transaction log. I wanted to see if I could corrupt a databases MDF and recover data even after the last t-log backup. This is where the tail backup comes in.

The tail log backup can recover your data even if the MDF is corrupted. This is because it stores all the transactions since the last full backup and t-log backup. If the MDF is corrupted your t-log should still be able  to be backed up, unless that is corrupted too. If the database is not truly corrupt, a backup log statement with the norecovery option will work just fine. This puts your database into recovery mode and prevents users from going into the database, preserving the state of the database so the restoration can be performed.

Unfortunately this does not work when the database is corrupted. You have to use the option continue_after_error, this forces the backup to occur.

You can then restore all data back to the database using your full and t-log backups.

Immediately after bringing the database online, be sure to make a full backup. This way you have a good restore point and if you routinely are backing up your t-logs, your next transactional backup will work just fine.

SQL Server Rebuild or Reoganize Your Indexes – It depends, but here is a script I use.

So if you are like me, chances are you have that one server where the reindexing or reorganizing is taking a long time to finish. I came up with a solution that has helped me reduce the time it takes to maintain my indexes.


Rebuilding indexes basically recreates an index from scratch (retrieving the data from the table again) whereas reorganizing is a process that relocates the pages of an index.

Rebuilding an Index

Rebuilding an index is typically an offline process, unless you have the Enterprise edition of SQL Server with the online flag set (check BOL for your particular version). While non-clustered indexes are being rebuilt, the table is available. However, rebuilding clustered indexes results in the the table being offline.

Reorganizing an Index

Reorganizing is an online process. It can reduce your fragmentation, but doesn’t always. Remember it is only moving pages around and not actually recreating the pages from data in the table.

Best Practices

Based on what I have read from various experts of SQL Server, rebuilding is recommended for indexes over 30 percent fragmentation. Under 30 percent, the index should be reorganized.

It is also recommended to not do anything to the indexes that are under 100 pages in size as they will not gain anything from a rebuild or reorganize. Of course, sometimes you might need to rebuild a small index, if for example, one of the pages has data corruption.

What the Script Does

Based on the best practices I mention above, it scans the sys.indexes view of every database on your SQL Server instance and then creates (and executes) rebuild or reogranize command for each index that has more than 5% fragmentation and more than 100 pages in size.

It uses the server default fill factor, which you can set in the properties of server instance.It currently DOES rebuild clustered indexes, so if you are running this be sure to run it in your maintenance window.

I encourage you to read through and understand the script as well as test it in your test environment before running it on production to get a feel for its behavior.

Let me know if it helps you out, I know it has helped me get more done in my maintenance window.

DECLARE @rebuildThreshold FLOAT;
SET @rebuildThreshold = 30.0;

CREATE TABLE #indices (
dbname VARCHAR(300),
tablename VARCHAR(300),
indexname VARCHAR(300),
fragmentation FLOAT

SELECT  name
FROM    sys.databases
WHERE   name<>’tempdb’  AND state_desc <> ‘OFFLINE’ AND is_read_only = 0

OPEN curs

SET @sql = ‘SELECT ”’ + @db + ”’,
”[” + SCHEMA_NAME(schema_id) + ”].[” + OBJECT_NAME(i.object_id, DB_ID(”’ + @db + ”’)) + ”]”,
i.name AS indexname,
FROM    sys.dm_db_index_physical_stats(DB_ID(”’ + @db + ”’), NULL, NULL, NULL, NULL) ips
INNER JOIN [‘ + @db + ‘].sys.indexes i ON ips.object_id=i.object_id AND
INNER JOIN [‘ + @db + ‘].sys.objects o ON i.object_id = o.object_id
WHERE   page_count>=100 AND
avg_fragmentation_in_percent > 5’;

INSERT  INTO #indices

CLOSE curs;

SELECT  CASE WHEN fragmentation<@rebuildThreshold THEN ‘ALTER INDEX ‘ + indexname + ‘ ON [‘ + dbname + ‘].’ + tablename + ‘ REORGANIZE;’
ELSE ‘ALTER INDEX ‘ + indexname + ‘ ON [‘ + dbname + ‘].’ + tablename + ‘ REBUILD;’
FROM    #indices
WHERE   indexname IS NOT NULL;

OPEN curs2;

EXEC (@sql);
PRINT @sql;


CLOSE curs2;

DROP TABLE #indices

Powershell ~ Shorten Shortcut Names

Renaming Files

Here is something I just came up with. It is a really short Powershell one-liner to remove the annoying ‘- Shortcut’ from your shortcuts.

dir “*- Shortcut*” | foreach{ren -Path $_.Name -NewName $_.Name.Replace(” – Shortcut”,””)}

It is a good idea to execute it first with -whatif in the foreach loop.

Note: Be sure to be in the desktop directory when you run this.

Powershell Retrieving Remote System Time

Compare Local Date and Time to a Remote Computer

This is a rather interesting problem. I was doing a comparison between an audit table and a trace for SQL Server, which was proving to be dificult as I soon realized there was latency as well as the system date’s had an offset. So I turned to my good old friend, Powershell. Powershell has a very nice interface for coding against WMI, which I fully leveraged in this code snippet.

#Server name here. 
$ServerName = <Server Name Here>
#Retreive the localtime of the server. 
$remoteDate = Get-WmiObject -ComputerName $ServerName -Class win32_operatingsystem -Property LocalDateTime
#Converting a WMI time to a standard datetime format. 
$remoteDate = [System.Management.ManagementDateTimeConverter]::ToDateTime($remoteDate.LocalDateTime)

$localDate = Get-Date

#Displaying the difference. 
$remoteDate - $localDate

SQL Server Null Values ~ Into the Void (pun intended)

Null values can get some people rather confused writing queries. I hope I can shed some light on that. By default, SQL Server uses ANSI Nulls. This behavior says that any value compared to null is not equal to null.

if ‘a’=null
print ‘true’
print ‘false’

Returns false

Here is something interesting and if you are slightly devious, what about null compared to null?

if null=null
print ‘true’
print ‘false’

Returns false

if null is null
print ‘true’
print ‘false’

Returns true

Lets turn off ANSI_Null:


if null=null
print ‘true’
print ‘false’ 


if null is null
print ‘true’
print ‘false’ 

Returns true

According to MSDN, if you are trying to search for or compare null values using “is null” is recommended and will return consistent results.

If you are trying to create a query and want to include nulls in the result set you have to do it explicitly like this:
WHERE name = ‘Smith’ OR name IS NULL
Or if you want to exclude nulls:
WHEREname = ‘Smith’ OR name IS NOT NULL

If you want to be tricky you could do something like:

WHERE ISNULL (name,) = ‘Smith’

In London, they have signs that say “Mind the gap”, I say MIND THE NULLS!

One handy function to deal with nulls is Coalesce, which I describe here.

Setting Up SharePoint Search Error: The Web application at could not be found.

If you are receiving this error:
The Web application at <URL> could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application.

Take a look in Central Administration > Operations > Alternate Access Mappings.

If there is no DNS entry for the server, replace the server name with the IP address. This will get your search capabilities working in most cases.

Here is a little background in my case that might help you. I setup a TFS server and wanted to configure the underlying WSS (Windows SharePoint Services).

Hope this helps!

Control Alt Delete in Remote Desktop

Step 1: Maximize your RDP window.

Step 2: Ctrl+Alt+Esc

Step 3: Do what you must.