PostgreSQL prend en charge la spécification DOMAIN
, à partir de SQL 2011 Spec Spec,
Un domaine est un objet désigné par l'utilisateur qui peut être spécifié comme alternative à un type de données dans certains endroits où un type de données peut être spécifié. Un domaine consiste en un type de données, éventuellement une option par défaut et des contraintes zéro ou plus (domaine).
Cela nous permet de faire des trucs vraiment cool comme mettre en œuvre un domaine pour la spécification HTML5 pour le courrier électronique sur un texte insensible à une casse Type . Cela garantit que tous les clients accédant à la base de données ont une vérification d'intégrité sur les données insérées.
CREATE DOMAIN email AS citext
CHECK ( value ~ '^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$' );
SQL Server prend-il en charge une telle fonctionnalité en dehors du système de déclenchement?
SQLCLR présente une surface pour créer des types de données entièrement personnalisés. En fait, c'est ainsi que SQL Server prend en charge les types de données géométriques et hiérarchies.
Étant donné que SQLCLR est basé sur le langage commun-intermédiaire Microsoft.Net, une grande variété de contraintes sont possibles pour un type de données SQLCLR. Par exemple, vous pouvez facilement vous assurer qu'une adresse e-mail provient d'un domaine valide en interrogeant DNS pour l'enregistrement MX dans le cadre du code de validation des données.
SQL Server peut indexer un CLR UDT tant que IsByteOrdered:=True
est défini. Il existe une tonne de propriétés comme celle-là, que vous pouvez modifier pour affecter la manière dont SQL Server utilise l'UDT. Pour une correspondance d'égalité comme celle requise par un index, SQL Server examine simplement la valeur binaire stockée dans la page I.E. Il n'a pas besoin de regarder le code UDT du tout.
À titre d'exemple d'un type défini par l'utilisateur SQLCLR qui vérifie un espace de domaine pour la validité, j'ai écrit le code de la preuve terrible suivant VB.NET CODE:
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
<Serializable()> _
<Microsoft.SqlServer.Server.SqlUserDefinedType(Format.UserDefined, IsByteOrdered:=True, MaxByteSize:=320, ValidationMethodName:="ValidateEmailAddress")> _
Public Structure EmailType
Implements INullable
Implements IBinarySerialize
Private m_Null As Boolean
Private m_EmailAddress As String
Public Function ValidateEmailAddress() As Boolean
'is the email address valid?
If Me.IsValidDomain Then
Return True
Else
Return False
End If
End Function
Public Overrides Function ToString() As String
Return Me.m_EmailAddress
End Function
Public ReadOnly Property IsNull() As Boolean Implements INullable.IsNull
Get
' Put your code here
If Me.m_EmailAddress Is Nothing Then
Me.m_Null = True
Else
Me.m_Null = False
End If
Return m_Null
End Get
End Property
Public Shared ReadOnly Property Null As EmailType
Get
Dim h As New EmailType
h.m_Null = True
Return h
End Get
End Property
'called when SQL Server passes in a SqlString value to the UDT
Public Shared Function Parse(ByVal s As SqlString) As EmailType
If s.IsNull Then
Return Null
End If
Dim u As New EmailType
u.m_EmailAddress = CType(s, String)
If u.ValidateEmailAddress = False Then
Throw New Exception("Invalid Email Address")
End If
Return u
End Function
Public Function IsValidDomain() As Boolean
Dim iAtSign As Int32 = Microsoft.VisualBasic.Strings.InStr(Me.m_EmailAddress, "@")
Dim iDomainLength As Int32 = Microsoft.VisualBasic.Strings.Len(Me.m_EmailAddress) - iAtSign
Dim sDomain As String = Microsoft.VisualBasic.Strings.Right(Me.m_EmailAddress, iDomainLength)
Dim bResolvable As Boolean = False
Try
Dim ip As System.Net.IPHostEntry = System.Net.Dns.GetHostEntry(sDomain)
bResolvable = True
Catch ex As Exception
Throw New Exception(Me.m_EmailAddress & " is not from a resolvable domain.")
End Try
Return bResolvable
End Function
' save the value to the database
Public Sub Write(w As System.IO.BinaryWriter) Implements IBinarySerialize.Write
w.Write(Me.m_EmailAddress)
End Sub
' retrieve the value from the database
Public Sub Read(r As System.IO.BinaryReader) Implements IBinarySerialize.Read
Dim sTemp As String = r.ReadString
Dim sTemp1 As String = ""
For Each n As Char In sTemp.ToCharArray
sTemp1 = sTemp1 & n.ToString
Next
Me.m_EmailAddress = sTemp
End Sub
End Structure
Étant donné que le code ci-dessus n'est pas signé, vous devez le tester uniquement sur une machine de développement où vous pouvez activer le paramètre de base de données TRUSTWORTHY
. Une fois le code compilé, vous l'importaez dans SQL Server via ce qui suit:
CREATE Assembly SQLCLREmailType
AUTHORIZATION dbo
FROM 'C:\Path\Goes\Here\SQLCLREmailType.dll'
WITH PERMISSION_SET = UNSAFE;
CREATE TYPE EmailType
EXTERNAL NAME SQLCLREmailType.[SQLCLREmailType.EmailType]
L'UDT peut ensuite être utilisé comme ceci:
DECLARE @t TABLE (
col EmailType NOT NULL
);
INSERT INTO @t (col)
VALUES ('[email protected]')
, ('[email protected]');
SELECT CONVERT(varchar(50), t.col)
FROM @t t
GO
Le code ci-dessus renvoie:
+ ------------------- + | (Pas de nom de colonne) | + ------------------ + | [email protected] | | [email protected] | [.____] + ------------------ + +
Cependant, lorsque vous essayez d'insérer une adresse appartenant à un domaine de messagerie inexistant, comme dans:
DECLARE @t TABLE (
col EmailType NOT NULL
);
INSERT INTO @t (col)
VALUES , ('us@asdfasdfasdfasdfasdfasdfasdfasdf90097809878907098908908908908.com');
SELECT CONVERT(varchar(50), t.col)
FROM @t t
GO
Vous voyez une erreur:
MSG 6522, niveau 16, État 2, ligne 27
[.____] Une erreur .NET Framework s'est produite lors de l'exécution de la routine ou de l'agrégat défini par l'utilisateur "EmailType":
[. ____.
System.Exception:
[.____] chez sqlclremailtype.emailype.isvaliddomain ()
[.____] chez sqlclremailtype.emailype.validateMailAmailAddress ()
[.____] à sqlclremailtype.emailype.parse (sqlstring s)
Je ne vais pas marquer cela comme choisi pour le moment, car il y a de mai Soyez un travail autour, mais techniquement, ils ne sont pas pris en charge. Vous pouvez voir le problème sur Microsoft Connect.
Bonjour Erland,
Après avoir soigneusement évalué tous les éléments de suggestion de notre pipeline , nous fermons des articles que nous ne mettrons pas dans un proche avenir en raison des éléments de priorité plus élevés actuels. Nous réévaluerons à nouveau les suggestions fermées à l'avenir sur la base de la feuille de route du produit.
Merci encore d'avoir fourni la suggestion du produit et le soutien continu de notre produit.
- Team Umaachandar, SQL Programmabilité
Le problème a été ouvert en 2012.