Interesting problem with SQL Server, ARITHABORT, filtered indexes, calculated columns, and compatibility mode of 80

I recently ran into a problem in a legacy application.  Someone had applied a unique index on a column in a SQL Server database table.  Shortly after, we started seeing some errors in our logs relating to that table:

UPDATE failed because the following SET options have incorrect settings: ‘ARITHABORT’. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.

After a good amount of investigation, I discovered that it was related to the fact that the unique index as a filtered index (it needed to be a filtered unique index because the business rules allowed for duplicate null values, but not duplicate non-null values) and it turns out that if you use a filtered index in SQL Server while running with Compatibility Mode = 80, then any updates to that table need to specify SET ARITHABORT ON, or it will fail with this error.

Well, this is a legacy application, which can’t have the compatibilty mode changed for numerous reasons, and there are many places where we would need to set ARITHABORT, so that wasn’t really a good option either.

First I tried a work around using a computed column that would never be null, and then I applied a unique index to that column, but the same ARITHABORT problem exists with computed columns as it does with filtered indexes.

After a few other attempts at a workround, my friend Phil @ XDev Group mentioned a method he used to solve a similar problem.  I created a trigger that would create a poor man’s calculated column, without the imposed limitations of using a real calculated column in compat80 mode.

CREATE TRIGGER [dbo].UniqueJobNumberGenerator ON [dbo].jobdata
    FOR INSERT, UPDATE
AS
    BEGIN
        SET NOCOUNT ON;

        UPDATE  dbo.jobdata
        SET     UniqueJobNumber = ( CASE WHEN [num] IS NULL
                                         THEN CONVERT([varchar], [id], ( 0 ))
                                              + '00000000'
                                         ELSE [num]
                                    END )
        WHERE   id IN ( SELECT   id
                               FROM     INSERTED )

    END

Then I applied a unique index on that column (without a filter) and … success!

Calculate Network Address

Here is a little console application I created that can take an ip and subnet mask and give you the network address. 

Module Module1

    Sub Main()
        Console.WriteLine("Enter the IP address")
        Dim sIP As String = Console.ReadLine()
        Console.WriteLine("Enter Subnet Mask")
        Dim sSubnetMask As String = Console.ReadLine()
        Dim ip() As String = sIP.Split(".")
        Dim subnetmask() As String = sSubnetMask.Split(".")
        Console.WriteLine("The network address is:")
        For i As Integer = 0 To 3
            If i > 0 Then
                Console.Write(".")
            End If
            Console.Write(ip(i) and subnetmask(i))
        Next
        Console.WriteLine("")
        Console.ReadLine()
    End Sub

End Module

EDIT: I was really not thinking clearly when I wrote the original.  Thanks to TheMoof for pointing this out.

Copy Group Membership From One User To Another

I couldn’t find an easy quick way to do this so I took an old powershell script I found and modified it to work in Windows 2008 R2 and later environments.

   1: import-module ActiveDirectory
   2: cls 
   3: write-output "This script adds the destination user to all the Groups which the source user is memberof." 
   4: write-output " " 
   5: write-output " " 
   6: $SName = Read-Host "Please Enter the alias name of the source user " 
   7: $DName = Read-Host "Please Enter the alias name of the Destination user " 
   8:  
   9: $K = Get-ADUser -Identity $SName -Properties memberOf
  10: foreach($group in $K.memberof)  
  11: {  
  12: Add-ADGroupMember -Identity $group -Member $DName 
  13: write-output $group 
  14: }  
  15:  

List of years in SQL Server

Here is a CTE from my friend Phil that returns a list of years in an efficient manner. Good reference.

/*Return a list of years since 2009*/

WITH yearlist
AS ( SELECT 2009 AS year
UNION ALL
SELECT yl.year + 1 AS year
FROM yearlist yl
WHERE yl.year + 1 <= YEAR(GETDATE())
)
SELECT year
FROM yearlist
ORDER BY year DESC;

Universe Sandbox

I bought this “game” on Steam for like 3 bucks. It’s called Universe Sandbox. Basically it’s a simulator. Aside from allowing you to watch all the orbits, zoom in/out etc, you can mess around with stuff. Here I added a ton of extra Jupiters to the vicinity of Earth’s orbit

clip_image001

They soon throw earth out of its orbit

clip_image002

What if all the small planets orbited earth

clip_image003

Screw up Saturn’s rings by adding Earth as a moon

clip_image004

clip_image005

clip_image006

Crash some galaxies together

clip_image007

clip_image008

Simulation to show how close Apophis will pass to the Earth

clip_image009

The La Grange points:

clip_image010

A very large star compared to our star:

clip_image011

Very cool.