UdtSsn.cs
using System.Data;
using System.Data.Sql;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text.RegularExpressions;
namespace Apress.ProSqlServerDatabaseDesign
{
//------------------------------------------------
// Purpose: Social Security number user-defined type
// Written: 12/17/2005
// Comment:
//
// SqlUserDefinedType attribute contains data used by SQL Server 2005
// at runtime and by the Professional version of Visual Studio
// and above at deployment tithis. UDT's must be serializable and implement INullable.
//
// Format.Native - indicates SQL server can Serialize the type for us
// Name - Name of UDT when created in SQL Server (used by VS at deployment)
// IsByteOrdered - indicates if type can be ordered (used by SQL Server at runtime)
// IsFixedLength - indicates if length of type is fixed (used by SQL Server at runtime)
//------------------------------------------------
[Serializable()]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native, Name = "SSN")]
public struct SsnUdt : INullable
{
// private members
private bool m_Null;
private int m_ssn;
public override string ToString()
{
// format SSN for output
return this.Ssn.ToString("000-00-0000");
}
// private property to set/get ssn stored as intger
private int Ssn
{
get { return m_ssn; }
set { m_ssn = value; }
}
public bool IsNull
{
get { return m_Null; }
}
// return our UDT as a null value
public static SsnUdt Null
{
get
{
SsnUdt h = new SsnUdt();
h.m_Null = true;
return h;
}
}
// get data from SQL Server as string and parse to return our UDT
public static SsnUdt Parse(SqlString s)
{
if (s.IsNull)
{
return Null;
}
// validate value being passed in as a valid SSN
if (IsSsnValid(s.ToString()))
{
SsnUdt u = new SsnUdt();
u.Ssn = ConvertSSNToInt(s.ToString());
return u;
}
throw new ArgumentException("SSN is not valid.");
}
// validate ssn using regex matching - returns true if valid, false if not
private static bool IsSsnValid(String ssn)
{
return (Regex.IsMatch(ssn,
"^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$",
RegexOptions.None));
}
// private function to convert SSN as a string to an integer
private static int ConvertSSNToInt(string ssn)
{
int ssnNumbers = 0;
try
{
// try a simple conversion
ssnNumbers = Convert.ToInt32(ssn);
}
catch
{
// if simple conversion fails, strip out everything
// but numbers and convert to integer
string ssnString = "";
for (int i = 0; i <= ssn.Length - 1; i++)
{
if ("0123456789".IndexOf(ssn[i]) >= 0)
{
ssnString += ssn[i];
}
}
ssnNumbers = Convert.ToInt32(ssnString);
}
return ssnNumbers;
}
}
}