Gewusst wie: Erstellen und Ausführen eines benutzerdefinierten CLR-SQL Server-Typs

Aktualisiert: November 2007

Erstellen Sie einen benutzerdefinierten SQL-Typ, indem Sie einem SQL Server-Projekt einen benutzerdefinierten Typ (Benutzerdefinierter Typ) hinzufügen. Nach erfolgreicher Bereitstellung kann dieser wie ein Systemtyp verwendet werden. Das schließt Spaltendefinitionen, Variablen, Parameter, Funktionsergebnisse, Cursor, Trigger und Replikation ein. Benutzerdefinierte Typen ermöglichen es dem Benutzer nicht nur, das SQL Server-Datentypsystem zu erweitern, sondern bieten darüber hinaus die Möglichkeit, komplex strukturierte Typen zu definieren.

Hinweis:

Das CLR-Integrationsfeature (Common Language Runtime) ist in Microsoft SQL Server in der Standardeinstellung deaktiviert und muss aktiviert werden, damit SQL Server-Projektelemente verwendet werden können. Die CLR-Integration kann mithilfe der Option CLR aktiviert der gespeicherten Prozedur sp_configure aktiviert werden. Weitere Informationen finden Sie unter Aktivieren der CLR-Integration.

Hinweis:

Ihr Computer zeigt möglicherweise für einige der Elemente der Visual Studio-Benutzeroberfläche in der folgenden Anleitung andere Namen oder Standorte an. Diese Elemente sind von der jeweiligen Visual Studio-Version und den verwendeten Einstellungen abhängig. Weitere Informationen finden Sie unter Visual Studio-Einstellungen.

Erstellen eines benutzerdefinierten Typs

So erstellen Sie einen benutzerdefinierten SQL-Typ

  1. Öffnen Sie ein bestehendes SQL Server-Projekt, oder erstellen Sie ein neues Projekt. Weitere Informationen finden Sie unter Gewusst wie: Erstellen eines SQL Server-Projekts.

  2. Wählen Sie im Menü Projekt die Option Neues Element hinzufügen aus.

  3. Wählen Sie in Dialogfeld "Neues Element hinzufügen" die Option Benutzerdefinierter Typ aus.

  4. Geben Sie einen Namen für den neuen benutzerdefinierten Typ ein.

  5. Fügen Sie Code zur Definition und Erstellung des benutzerdefinierten Typs hinzu. Beachten Sie das erste Beispiel, das dieser Prozedur folgt.

    Hinweis:

    C++-Beispiele müssen mit der /clr:safe-Compileroption kompiliert werden.

  6. Öffnen Sie für Visual Basic und Visual C# im Projektmappen-Explorer den Ordner TestScripts, und doppelklicken Sie auf die Datei Test.sql.

    Doppelklicken Sie für Visual C++ im Projektmappen-Explorer auf die Datei debug.sql.

  7. Fügen Sie der Datei Test.sql (bzw. debug.sql in Visual C++) Code hinzu, um den benutzerdefinierten Typ auszuführen. Beachten Sie das zweite Beispiel, das dieser Prozedur folgt.

  8. Drücken Sie F5, um den benutzerdefinierten Typ zu erstellen, bereitzustellen und zu debuggen. Informationen zum Bereitstellen ohne Debuggen finden Sie unter Gewusst wie: Bereitstellen von SQL Server-Projektelementen auf einem SQL-Server.

  9. Zeigen Sie die Ergebnisse im Ausgabefenster an, und wählen Sie Ausgabe anzeigen von: Datenbankausgabe aus.

Beispiel

In diesem Beispiel wird der Typ Point erstellt, den Sie wie andere einfache Typen verwenden können. Die Klassendeklaration wird mit den Attributen Serializable und SqlUserDefinedTypeAttribute versehen. Die Format-Eigenschaft von SqlUserDefinedTypeAttribute legt das Speicherformat des benutzerdefinierten Typs fest. Der Typ implementiert eine Zeichenfolgenkonvertierung, indem die Methoden Parse und ToString implementiert werden. Der Typ implementiert außerdem zwei Eigenschaftenprozeduren, um die Werte von X und Y für den von dieser Klasse dargestellten Punkt abzurufen und festzulegen.

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;
    }
};

Fügen Sie der Datei Test.sql (bzw. debug.sql in Visual C++) im Ordner TestScripts des Projekts Code hinzu, um den benutzerdefinierten Typ (Point) auszuführen und zu testen. Um den neuen Typ zu testen, erstellen Sie z. B. eine Tabelle, die diesen Typ verwendet. Im folgenden Beispiel wird gezeigt, wie der Point-Typ bei der Tabellenerstellung verwendet wird.

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

Siehe auch

Aufgaben

Gewusst wie: Erstellen eines SQL Server-Projekts

Gewusst wie: Erstellen und Ausführen einer gespeicherten CLR SQL Server-Prozedur

Gewusst wie: Erstellen und Ausführen eines CLR SQL Server-Triggers

Gewusst wie: Erstellen und Ausführen eines CLR SQL Server-Aggregats

Gewusst wie: Erstellen und Ausführen einer benutzerdefinierten CLR SQL Server-Funktion

Gewusst wie: Erstellen und Ausführen eines benutzerdefinierten CLR-SQL Server-Typs

Exemplarische Vorgehensweise: Erstellen einer gespeicherten Prozedur in verwaltetem Code

Gewusst wie: Debuggen einer gespeicherten Prozedur in SQL/CLR

Konzepte

Einführung in CLR-Integration für SQL Server (ADO.NET)

Vorteile von verwaltetem Code bei der Erstellung von Datenbankobjekten

Elementvorlagen für SQL Server-Projekte

Referenz

Attribute für SQL Server-Projekte und Datenbankobjekte

Weitere Ressourcen

Debuggen von SQL CLR-Datenbanken