SQLCLR trình bày một diện tích bề mặt để tạo các kiểu dữ liệu hoàn toàn tùy chỉnh. Trong thực tế, đó là cách SQL Server hỗ trợ các kiểu dữ liệu hình học và phân cấp.
Do SQLCLR dựa trên ngôn ngữ trung gian phổ biến Microsoft.Net, nên có nhiều ràng buộc lớn đối với kiểu dữ liệu SQLCLR. Chẳng hạn, bạn có thể dễ dàng đảm bảo địa chỉ email đến từ một miền hợp lệ bằng cách truy vấn DNS cho bản ghi MX như một phần của mã xác thực dữ liệu.
SQL Server có thể lập chỉ mục UDR CLT miễn là IsByteOrdered:=True
được đặt. Có rất nhiều thuộc tính như thế, mà bạn có thể thay đổi để ảnh hưởng đến cách SQL Server sử dụng UDT. Để khớp bằng như yêu cầu của một chỉ mục, SQL Server chỉ cần xem giá trị nhị phân được lưu trữ trong trang tức là không cần phải xem mã UDT.
Như một ví dụ về loại SQLCLR do người dùng định nghĩa kiểm tra tính hợp lệ của không gian miền, tôi đã viết mã VB.Net bằng chứng khủng khiếp về khái niệm sau:
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
Vì mã ở trên chưa được ký, bạn chỉ nên kiểm tra mã trên máy phát triển nơi bạn có thể bật TRUSTWORTHY
cài đặt cơ sở dữ liệu. Sau khi mã được biên dịch, bạn nhập mã vào SQL Server thông qua các bước sau:
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 sau đó có thể được sử dụng như thế này:
DECLARE @t TABLE (
col EmailType NOT NULL
);
INSERT INTO @t (col)
VALUES ('mvernon@mvct.com')
, ('us@them.com');
SELECT CONVERT(varchar(50), t.col)
FROM @t t
GO
Mã trên trả về:
+ ------------------ +
| (Không có tên cột) |
+ ------------------ +
| mvernon@mvct.com |
| us@them.com |
+ ------------------ +
Tuy nhiên, khi cố gắng chèn một địa chỉ thuộc về một tên miền email không tồn tại, như trong:
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
Bạn thấy một lỗi:
Msg 6522, Cấp 16, Trạng thái 2, Dòng 27 Đã
xảy ra lỗi .NET Framework trong khi thực hiện quy trình do người dùng xác định hoặc tổng hợp "EmailType":
System.Exception: us@asdfasdfasdfasdfasdfasdfasdfasdf90097809878907098908908908908.com không phải là từ một miền.
System.Exception:
tại SQLCLREmailType.EmailType.IsValidDomain ()
tại SQLCLREmailType.EmailType.ValidateEmailAddress ()
tại SQLCLREmailType.EmailType.Pude (SqlString s)