Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Interazione con il Framwork .NET

Creazione di un contenitore di funzioni in .NET da inserire in SQL Server e da far funzionare tramite T-SQL
Creazione di un contenitore di funzioni in .NET da inserire in SQL Server e da far funzionare tramite T-SQL
Link copiato negli appunti

Grazie al Framework .NET è stato introdotto il nuovo concetto di Assembly e reference. In pratica, adesso possiamo creare un semplice contenitore di funzioni (dll) e farla funzionare da tutti i programmi che sfruttano il Framework.

Visto che anche SQL Server fa parte di questi programmi, allo stesso modo possiamo creare un assembly in .NET, inserirlo in SQL Server e da questo eseguirlo tramite un comando T-SQL.

Figura 1. Inclusione di una DLL in SQL Server 2005
Inclusione di una DLL in SQL Server 2005

Creazione del progetto .NET

Per creare il progetto utilizziamo Visual Studio 2005. Creiamo un nuovo progetto di tipo libreria di classi, lo chiamiamo DATA_FSX, ovvero funzioni per i dati e lo salviamo. A questo punto dobbiamo inserire una nuova classe che chiamiamo Motore.

Listato 1. Classe Motore

Imports System
Imports System.Data
Imports System.Data.SqlClient

Public Class Motore

    'Inizializzo connessione e datareader
    Private Const SQLCONN As String = "context connection=true"
    Private CN As SqlConnection
    Private CMD As SqlCommand    
    Private DR As SqlDataReader

    Public Shared Function Saluta() As Integer
        InviaSQL("Ciao da VB.NET!!")
        Return 0    
    End Function
    
    'Funzioni in Overload per inviare al motore di database le richieste
    
    Public Shared Sub InviaSQL(ByVal value As String)
        Microsoft.SqlServer.Server.SqlContext.Pipe.Send(value)
    End Sub Public Shared
    
    
    Sub InviaSQL(ByVal value As SqlDataReader)
        Microsoft.SqlServer.Server.SqlContext.Pipe.Send(value)
    End Sub
    
    
    Public Shared Sub InviaSQL(ByVal value As Microsoft.SqlServer.Server.SqlDataRecord)
        Microsoft.SqlServer.Server.SqlContext.Pipe.Send(value)
    End Sub

End Class

Figura 2. Risultato classe Motore
Risultato classe Motore

Abbiamo messo nella classe una serie di oggetti che ci consentono di eseguire operazioni sul database. Poi abbiamo creato in overloads, ovvero con lo stesso nome ma parametri di tipo diverso, una routine che invia i messaggi o i dati a SQL.

La prima funzione saluta(), dichiarata Shared (altrimenti non sarebbe visibile e utilizzabile da SQL), invia un semplice test sull'output. Per poter eseguire la funzione dobbiamo prima compilare la dll e andare a vedere dove è stata compilata. Poi apriamo l'editor T-SQL ed eseguiamo lo script per registrare l'assembly e associare una Stored Procedure alla funzione Saluta().

Listato 2. Registrazione assembly

CREATE ASSEMBLY [DATA_FSX]
FROM 'D:DATABASEDATA_FSXDATA_FSXbinReleaseDATA_FSX.dll'
WITH PERMISSION_SET = SAFE

--Associo una funzione dell' assembly ad una stored procedure
CREATE PROCEDURE Saluta

AS EXTERNAL NAME DATA_FSX.[DATA_FSX.Motore].Saluta

--eseguo la stored procedure
EXEC Saluta

Questa è il metodo standard per poter lavorare con SQLCLR, ovvero il linguaggio che fa da tramite tra .NET e SQL server.

Funzioni avanzate

Il secondo passo che dobbiamo fare è quello di interagire con i dati. Nella seconda funzione dobbiamo eseguire una SELECT e restituire dei dati particoli, filtrati. Quindi la funzione dovrà anche ricevere un parametro di input.

Nota: stiamo usando un assembly di tipo Shared, quindi alcune operazioni quali variabili locali o dispersione di dati, non sono consentite. In secondo luogo, ogni volta che modifichiamo il contenuto dell'assembly (dll), dobbiamo ricompilare, cancellare riferimenti (stored procedure) e sovrascrivere la vecchia registrazione assembly con una nuova. Questo perchè l'assembly è stato inglobato da SQL Server.

Per prima cosa modifichiamo la classe motore con questa nuova funzione.

Listato 3. Funzione per ordini

'Ricerca ordini per ID cliente
Public Shared Function Seleziona_Ordini(ByVal cliente As Int32) As Integer
    'dichiaro qui le variabili perchè la funzione è shared
    Dim CN As SqlConnection
    Dim CMD As SqlCommand
    Dim DR As SqlDataReader
    'Istruzione SQL
    CN = New SqlConnection("context connection=true")
    CN.Open() CMD = New SqlCommand("SELECT ANA_NOME, ANA_COGNOME,ORD_CODICE
    " & _
    "FROM ANAGRAFICA INNER JOIN ORDINI " & _
    "ON ANAGRAFICA.ANA_ID = ORDINI.ORD_ID_ANA " & _
    "WHERE ANA_ID = " & cliente, CN)
    '-->inviamo il lettore carico di dati
    DR = CMD.ExecuteReader
    InviaSQL(DR)
    Return 0
End Function

Adesso dobbiamo registrare nuovamente tutto, questa volta però, quando andiamo a registrare la stored procedure, SQL ci fornirà un messaggio di errore perchè necessita di una variabile per passare il valore di cliente alla funzione VB. Nel listato 4.

Listato 4. Dichiarazione assembly con variabile

CREATE PROCEDURE Seleziona_Ordini
(@Cliente int)
AS EXTERNAL NAME DATA_FSX.[DATA_FSX.Motore].Seleziona_Ordini

SQLCLR consente di rendere il database uno strumento completo, in grado di effettuare anche operazioni complesse, non sempre eseguibili con il solo motore di database. Dobbiamo dire che in prima esecuzione, gli assembly sono più lenti di una normale query, ma una volta cachati si eguagliano.

Ti consigliamo anche