Condividi tramite


Procedura: creare ed eseguire un tipo CLR definito dall'utente di SQL Server

Aggiornamento: novembre 2007

Creare un tipo definito dall'utente SQL aggiungendo un Tipo definito dall'utente a un progetto SQL Server. Dopo la distribuzione, sarà possibile utilizzarlo in tutti i contesti in cui si utilizza un tipo di sistema, inclusi definizioni di colonne, variabili, parametri, risultati di funzioni, cursori, trigger e replica. I tipi definiti dall'utente offrono l'estensibilità del sistema dei tipi di dati di SQL Server, nonché la capacità di definire tipi strutturati complessi.

Nota:

Per impostazione predefinita, in Microsoft SQL Server la funzionalità di integrazione di Common Language Runtime (CLR) è disattivata e deve essere attivata per poter utilizzare gli elementi del progetto SQL Server. Per attivare la funzionalità di integrazione di CLR, utilizzare l'opzione clr enabled della stored procedure sp_configure. Per ulteriori informazioni, vedere Attivazione dell'integrazione CLR.

Nota:

Nel computer in uso è possibile che vengano visualizzati nomi o percorsi diversi per alcuni elementi dell'interfaccia utente di Visual Studio nelle istruzioni seguenti. La versione di Visual Studio in uso e le impostazioni configurate determinano questi elementi. Per ulteriori informazioni vedere Impostazioni di Visual Studio.

Creazione di un tipo definito dall'utente

Per creare un tipo definito dall'utente SQL

  1. Aprire un Progetto SQL Server esistente o crearne uno nuovo. Per ulteriori informazioni, vedere Procedura: creare un progetto SQL Server.

  2. Scegliere Aggiungi nuovo elemento dal menu Progetto.

  3. Selezionare Tipo definito dall'utente nella Finestra di dialogo Aggiungi nuovo elemento.

  4. Nella casella Nome digitare un nome per il nuovo tipo definito dall'utente.

  5. Aggiungere il codice per definire e creare il tipo definito dall'utente. Vedere il primo esempio che segue questa procedura.

    Nota:

    Gli esempi di C++ devono essere compilati con l'opzione del compilatore /clr:safe.

  6. Per Visual Basic e Visual C#, in Esplora soluzioni aprire la cartella Script di test e fare doppio clic sul file Test.sql.

    Per Visual C++, in Esplora soluzioni fare doppio clic sul file debug.sql.

  7. Aggiungere il codice al file Test.sql (debug.sql in Visual C++) per eseguire il tipo definito dall'utente. Vedere il secondo esempio che segue questa procedura.

  8. Premere F5 per compilare, distribuire ed eseguire il debug del tipo definito dall'utente. Per informazioni sulla distribuzione senza debug, vedere Procedura: distribuire elementi del progetto SQL Server su SQL Server.

  9. Visualizzare i risultati presenti nella Finestra di output e selezionare Mostra output di: Output database.

Esempio

Nell'esempio viene creato un tipo Point che è possibile utilizzare come qualsiasi altro tipo semplice. La dichiarazione di classe è decorata con gli attributi Serializable e SqlUserDefinedTypeAttribute. La proprietà Format di SqlUserDefinedTypeAttribute determina il formato di archiviazione del tipo definito dall'utente. Il tipo consente di implementare la conversione delle stringhe mediante l'implementazione dei metodi Parse e ToString. Consente inoltre di implementare due routine di proprietà per ottenere e impostare i valori X e Y relativi al punto rappresentato dalla 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;
    }
};

Aggiungere il codice per eseguire e verificare il tipo definito dall'utente (Point) al file Test.sql (debug.sql in Visual C++) nella cartella Script di test del progetto. Per verificare il nuovo tipo, ad esempio, creare una tabella che ne faccia uso. Nell'esempio riportato di seguito viene illustrato come utilizzare il tipo Point nella creazione di una tabella.

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

Vedere anche

Attività

Procedura: creare un progetto SQL Server

Procedura: creare ed eseguire una stored procedure CLR di SQL Server

Procedura: creare ed eseguire un trigger CLR di SQL Server

Procedura: creare ed eseguire un aggregato CLR di SQL Server

Procedura: creare ed eseguire una funzione CLR definita dall'utente di SQL Server

Procedura: creare ed eseguire un tipo CLR definito dall'utente di SQL Server

Procedura dettagliata: creazione di una stored procedure nel codice gestito

Procedura: eseguire il debug di una stored procedure CLR SQL

Concetti

Introduzione all'integrazione con CLR di SQL Server (ADO.NET)

Vantaggi dell'utilizzo di codice gestito per creare oggetti di database

Modelli di elementi per progetti SQL Server

Riferimenti

Attributi per oggetti di database e progetti SQL Server

Altre risorse

Esecuzione del debug di database CLR SQL