PostgreSQLは、SQL 2011ワーキングドラフト仕様のDOMAIN
仕様 をサポートしています。
ドメインは、データ型を指定できる特定の場所で、データ型の代替として指定できる名前付きのユーザー定義オブジェクトです。ドメインは、データ型、場合によってはデフォルトオプション、および0個以上の(ドメイン)制約で構成されます。
これにより、 のような本当にクールなことを行うことができますdomainを実装して、大文字と小文字を区別しないテキストでメールのHTML5-spec type。 データベースにアクセスするすべてのクライアントに、挿入されたデータの整合性チェックがあることを保証します。
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は、トリガーシステムの外部でこのような機能をサポートしていますか?
SQLCLRは、完全にカスタムのデータ型を作成するための表面領域を提供します。実際、これがSQL Serverが幾何データ型と階層データ型をサポートする方法です。
SQLCLRはMicrosoft.Net共通中間言語に基づいているため、SQLCLRデータ型にはさまざまな制約が可能です。たとえば、データ検証コードの一部としてMXレコードのDNSをクエリすることで、メールアドレスが有効なドメインからのものであることを簡単に確認できます。
SQL Serverは、IsByteOrdered:=True
が設定されている限り、CLR UDTにインデックスを付けることができます。そのような多くのプロパティがあり、SQL ServerがUDTを使用する方法に影響を与えるように変更できます。インデックスに必要な同等性マッチングの場合、SQL Serverはページに格納されているバイナリ値を確認するだけです。つまり、UDTコードを確認する必要はまったくありません。
ドメインスペースの有効性をチェックするSQLCLR User-defined-typeの例として、次のひどい概念実証VB.Netコードを記述しました。
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
上記のコードは署名されていないため、TRUSTWORTHY
データベース設定を有効にできる開発マシンでのみテストする必要があります。コードをコンパイルしたら、次の方法でSQL Serverにインポートします。
CREATE Assembly SQLCLREmailType
AUTHORIZATION dbo
FROM 'C:\Path\Goes\Here\SQLCLREmailType.dll'
WITH PERMISSION_SET = UNSAFE;
CREATE TYPE EmailType
EXTERNAL NAME SQLCLREmailType.[SQLCLREmailType.EmailType]
UDTは次のように使用できます。
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
上記のコードは次を返します:
+ ------------------ + | (列名なし)| + ------------------ + | [email protected] | | [email protected] | + ------------------ +
ただし、次のように、存在しないメールドメインに属するアドレスを挿入しようとすると、
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
エラーが表示されます:
メッセージ6522、レベル16、状態2、行27
ユーザー定義ルーチンまたは集計「EmailType」の実行中に.NET Frameworkエラーが発生しました:
System.Exception:us@asdfasdfasdfasdfasdfasdfasdfasdf90097809878907098908908908908.com is not from a resolvable domain。
System.Exception:
at SQLCLREmailType.EmailType.IsValidDomain()
at SQLCLREmailType.EmailType.ValidateEmailAddress()
at SQLCLREmailType.EmailType.Parse(SqlString s)
may回避策があるため、これを選択済みとしてマークするつもりはありませんが、技術的にはサポートされていません。あなたは問題を見ることができます Microsoft Connect上で
こんにちはアーランド、
パイプライン内のすべての提案項目を注意深く評価した後、現在優先度の高い項目のために近い将来実装されない項目をクローズします。クローズされた提案は、今後、製品ロードマップに基づいて再評価します。
製品の提案と製品の継続的なサポートを提供していただき、ありがとうございます。
-SQLプログラマビリティチームUmachandar
この問題は2012年に公開されました。