Comment : créer et exécuter un type défini par l'utilisateur SQL Server CLR
Mise à jour : novembre 2007
Créez un type défini par l'utilisateur SQL en ajoutant un Type défini par l'utilisateur à un projet SQL Server. Une fois le déploiement réussi, vous pouvez l'utiliser dans tous les contextes dans lesquels vous pouvez utiliser un type de système. Cela inclut les définitions de colonne, les variables, les paramètres, les résultats de fonction, les curseurs, les déclencheurs et la réplication. Les types définis par l'utilisateur permettent à celui-ci d'étendre le système de type de données SQL Server, ainsi que de définir des types structurés complexes.
Remarque : |
---|
La fonctionnalité d'intégration du Common Language Runtime (CLR) est désactivée par défaut dans Microsoft SQL Server et doit être activée pour utiliser des éléments de projet SQL Server. Pour activer l'intégration du CLR, utilisez l'option clr enabled de la procédure stockée sp_configure. Pour plus d'informations, consultez Activation de l'intégration CLR. |
Remarque : |
---|
Il est possible que votre ordinateur affiche des noms ou des emplacements différents pour certains des éléments d'interface utilisateur Visual Studio dans les instructions suivantes. L'édition de Visual Studio dont vous disposez et les paramètres que vous utilisez déterminent ces éléments. Pour plus d'informations, consultez Paramètres Visual Studio. |
Création d'un type défini par l'utilisateur
Pour créer un type défini par l'utilisateur SQL
Ouvrez un Projet SQL Server existant ou créez-en un. Pour plus d'informations, consultez Comment : créer un projet SQL Server.
Dans le menu Projet, sélectionnez Ajouter un nouvel élément.
Sélectionnez Type défini par l'utilisateur dans la Ajouter un nouvel élément, boîte de dialogue.
Tapez un Nom pour le nouveau type défini par l'utilisateur.
Ajoutez le code pour définir et créer le type défini par l'utilisateur. Consultez le premier exemple qui suit cette procédure.
Remarque : Les exemples C++ doivent être compilés avec l'option du compilateur /clr:safe.
Pour Visual Basic et Visual C#, dans l'Explorateur de solutions, ouvrez le dossier TestScripts et double-cliquez sur le fichier Test.sql.
Pour Visual C++, dans l'Explorateur de solutions, double-cliquez sur le fichier debug.sql.
Ajoutez au fichier Test.sql (debug.sql en Visual C++) le code permettant d'exécuter le type défini par l'utilisateur. Consultez le deuxième exemple qui suit cette procédure.
Appuyez sur F5 pour générer, déployer et déboguer le type défini par l'utilisateur. Pour plus d'informations sur le déploiement sans débogage, consultez Comment : déployer des éléments de projet SQL Server sur un serveur SQL Server.
Consultez les résultats affichés dans la Sortie, fenêtre et sélectionnez Afficher la sortie à partir de : Sortie de base de données.
Exemple
Cet exemple crée un type Point que vous pouvez utiliser comme s'il s'agissait de tout autre type simple. La déclaration de classe est décorée à la fois avec Serializable et avec les attributs SqlUserDefinedTypeAttribute. La propriété Format de SqlUserDefinedTypeAttribute détermine le format de stockage du type défini par l'utilisateur. Le type implémente la conversion de chaînes à l'aide des méthodes Parse et ToString. Il implémente également deux procédures de propriété afin d'obtenir et de définir les valeurs de X et Y pour le point représenté par cette classe.
Imports System
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
<Serializable()> _
<SqlUserDefinedType(Format.Native)> _
Public Structure Point
Implements INullable
Private m_x As Int32
Private m_y As Int32
Private is_Null As Boolean
Public Property X() As Int32
Get
Return (Me.m_x)
End Get
Set(ByVal Value As Int32)
m_x = Value
End Set
End Property
Public Property Y() As Int32
Get
Return (Me.m_y)
End Get
Set(ByVal Value As Int32)
m_y = Value
End Set
End Property
Public ReadOnly Property IsNull() As Boolean Implements INullable.IsNull
Get
Return is_Null
End Get
End Property
Public Shared ReadOnly Property Null() As Point
Get
Dim pt As Point = New Point
pt.is_Null = True
Return pt
End Get
End Property
Public Overrides Function ToString() As String
If Me.IsNull() Then
Return Nothing
Else
Return Me.m_x & ":" & Me.m_y
End If
End Function
Public Shared Function Parse(ByVal s As SqlString) As Point
If s = SqlString.Null Then
Return Null
End If
If s.ToString() = SqlString.Null.ToString() Then
Return Null
End If
If s.IsNull Then
Return Null
End If
'Parse input string here to separate out coordinates
Dim str As String = Convert.ToString(s)
Dim xy() As String = str.Split(":"c)
Dim pt As New Point()
pt.X = CType(xy(0), Int32)
pt.Y = CType(xy(1), Int32)
Return (pt)
End Function
Public Function Quadrant() As SqlString
If m_x = 0 And m_y = 0 Then
Return "centered"
End If
Dim stringResult As String = ""
Select Case m_x
Case 0
stringResult = "center"
Case Is > 0
stringResult = "right"
Case Is < 0
stringResult = "left"
End Select
Select Case m_y
Case 0
stringResult = stringResult & " center"
Case Is > 0
stringResult = stringResult & " top"
Case Is < 0
stringResult = stringResult & " bottom"
End Select
Return stringResult
End Function
End Structure
using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
[Serializable()]
[SqlUserDefinedType(Format.Native)]
public struct Point : INullable
{
private Int32 m_x;
private Int32 m_y;
private bool is_Null;
public Int32 X
{
get
{
return (this.m_x);
}
set
{
m_x = value;
}
}
public Int32 Y
{
get
{
return (this.m_y);
}
set
{
m_y = value;
}
}
public bool IsNull
{
get
{
return is_Null;
}
}
public static Point Null
{
get
{
Point pt = new Point();
pt.is_Null = true;
return (pt);
}
}
public override string ToString()
{
if (this.IsNull)
{
return "NULL";
}
else
{
return this.m_x + ":" + this.m_y;
}
}
public static Point Parse(SqlString s)
{
if (s.IsNull)
{
return Null;
}
// Parse input string here to separate out coordinates
string str = Convert.ToString(s);
string[] xy = str.Split(':');
Point pt = new Point();
pt.X = Convert.ToInt32(xy[0]);
pt.Y = Convert.ToInt32(xy[1]);
return (pt);
}
public SqlString Quadrant()
{
if (m_x == 0 && m_y == 0)
{
return "centered";
}
SqlString stringReturn = "";
if (m_x == 0)
{
stringReturn = "center";
}
else if (m_x > 0)
{
stringReturn = "right";
}
else if (m_x < 0)
{
stringReturn = "left";
}
if (m_y == 0)
{
stringReturn = stringReturn + " center";
}
else if (m_y > 0)
{
stringReturn = stringReturn + " top";
}
else if (m_y < 0)
{
stringReturn = stringReturn + " bottom";
}
return stringReturn;
}
}
#include "stdafx.h"
#using <System.dll>
#using <System.Data.dll>
#using <System.Xml.dll>
using namespace System;
using namespace System::Data;
using namespace System::Data::Sql;
using namespace System::Data::SqlTypes;
using namespace Microsoft::SqlServer::Server;
// In order to debug your User-Defined Types, add the following to your debug.sql file:
//
// CREATE TABLE test_table (column1 Point)
//
// INSERT INTO test_table (column1) VALUES ('1:2')
// INSERT INTO test_table (column1) VALUES ('-2:3')
// INSERT INTO test_table (column1) VALUES ('-3:-4')
//
// SELECT column1.Quadrant() FROM test_table
//
// DROP TABLE test_table
//
[Serializable]
[SqlUserDefinedType(Format::Native)]
public value struct Point : public INullable
{
private:
Int32 m_x;
Int32 m_y;
bool is_Null;
public:
property Int32 X
{
Int32 get() { return (this->m_x); }
void set(Int32 value) { m_x = value; }
}
property Int32 Y
{
Int32 get() { return (this->m_y); }
void set(Int32 value) { m_y = value; }
}
virtual property bool IsNull
{
bool get() { return is_Null; }
}
static property Point Null
{
Point get()
{
Point pt;
pt.is_Null = true;
return (pt);
}
}
virtual String ^ToString() override
{
if (this->IsNull)
{
return "NULL";
}
else
{
return this->m_x + ":" + this->m_y;
}
}
static Point Parse(SqlString s)
{
if (s.IsNull)
{
return Null;
}
// Parse input string here to separate out coordinates
String ^str = Convert::ToString(s);
array<String ^> ^xy = str->Split(':');
Point pt;
pt.X = Convert::ToInt32(xy[0]);
pt.Y = Convert::ToInt32(xy[1]);
return (pt);
}
SqlString Quadrant()
{
if (m_x == 0 && m_y == 0)
{
return "centered";
}
SqlString stringReturn = "";
if (m_x == 0)
{
stringReturn = "center";
}
else if (m_x > 0)
{
stringReturn = "right";
}
else if (m_x < 0)
{
stringReturn = "left";
}
if (m_y == 0)
{
stringReturn = stringReturn + SqlString(" center");
}
else if (m_y > 0)
{
stringReturn = stringReturn + SqlString(" top");
}
else if (m_y < 0)
{
stringReturn = stringReturn + SqlString(" bottom");
}
return stringReturn;
}
};
Ajoutez le code permettant d'exécuter et de tester votre type défini par l'utilisateur (Point) au fichier Test.sql (debug.sql en Visual C++) situé dans le dossier TestScripts de votre projet. Par exemple, pour vérifier le nouveau type, créez une table qui l'utilise. L'exemple suivant illustre l'utilisation du type Point lors de la création de la table.
CREATE TABLE test_table (column1 Point)
go
INSERT INTO test_table (column1) VALUES ('1:2')
INSERT INTO test_table (column1) VALUES ('-2:3')
INSERT INTO test_table (column1) VALUES ('-3:-4')
select column1.Quadrant() from test_table
Voir aussi
Tâches
Comment : créer un projet SQL Server
Comment : créer et exécuter une procédure stockée SQL Server CLR
Comment : créer et exécuter un déclencheur SQL Server CLR
Comment : créer et exécuter un agrégat SQL Server CLR
Comment : créer et exécuter une fonction définie par l'utilisateur SQL Server CLR
Comment : créer et exécuter un type défini par l'utilisateur SQL Server CLR
Procédure pas à pas : création d'une procédure stockée dans le code managé
Comment : déboguer une procédure stockée SQL CLR
Concepts
Présentation de l'intégration de CLR dans SQL Server (ADO.NET)
Avantages de l'utilisation de code managé pour créer des objets de base de données
Modèles d'élément pour les projets SQL Server
Référence
Attributs pour les projets SQL Server et les objets de base de données