Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
L'esempio InProcessDataAccess contiene una serie di funzioni semplici che illustrano varie funzionalità del provider di accesso ai dati in-process di SQL Server CLR.
Prerequisiti
Per creare ed eseguire questo progetto, è necessario installare il software seguente:
SQL Server o SQL Server Express. È possibile ottenere gratuitamente SQL Server Express dalla documentazione di SQL Server Express e dal sito Web degli esempi
Database AdventureWorks disponibile nel sito Web per sviluppatori di SQL Server
.NET Framework SDK 2.0 o versione successiva o Microsoft Visual Studio 2005 o versione successiva. È possibile ottenere gratuitamente .NET Framework SDK.
Inoltre, devono essere soddisfatte le condizioni seguenti:
L'istanza di SQL Server in uso deve avere l'integrazione CLR abilitata.
Per abilitare l'integrazione con CLR, seguire questa procedura:
Abilitazione dell'integrazione con CLR
- Eseguire i comandi di Transact-SQL seguenti:
sp_configure 'clr enabled', 1GORECONFIGUREGOAnnotazioni
Per abilitare CLR, è necessario disporre
ALTER SETTINGSdell'autorizzazione a livello di server, che viene mantenuta in modo implicito dai membri dei ruoli predefiniti delsysadminserver eserveradmin.Il database AdventureWorks deve essere installato nell'istanza di SQL Server in uso.
Se non si è un amministratore per l'istanza di SQL Server in uso, è necessario disporre di un amministratore che conceda l'autorizzazione CreateAssembly per completare l'installazione.
Compilazione dell'esempio
Creare ed eseguire l'esempio usando le istruzioni seguenti:
Aprire un prompt dei comandi di Visual Studio o .NET Framework.
Se necessario, creare una directory per l'esempio. Per questo esempio si userà C:\MySample.
In c:\MySample creare
inprocda.vb(per l'esempio di Visual Basic) oinprocda.cs(per l'esempio C#) e copiare il codice di esempio di Visual Basic o C# appropriato (di seguito) nel file.Compilare il codice di esempio nell'assembly necessario dal prompt della riga di comando eseguendo una delle opzioni seguenti, a seconda del linguaggio scelto.
Vbc /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll,C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll,C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /target:library InProcDA.vbCsc /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.XML.dll /target:library inprocda.cs
Copiare il codice di installazione Transact-SQL in un file e salvarlo come
Install.sqlnella directory di esempio.Se l'esempio viene installato in una directory diversa,
C:\MySample\modificare il fileInstall.sqlcome indicato in modo che punti a tale percorso.Distribuire l'assembly, la stored procedure e le funzioni eseguendo
sqlcmd -E -I -i install.sql
Copiare il codice di installazione Transact-SQL in un file e salvarlo come
test.sqlnella directory di esempio.Testare l'applicazione eseguendo la riga seguente al prompt dei comandi:
sqlcmd -E -I -i test.sql
Copiare lo script di pulizia Transact-SQL in un file e salvarlo come
cleanup.sqlnella directory di esempio.Eseguire lo script con il comando seguente
sqlcmd -E -I -i cleanup.sql
Codice di esempio
Di seguito sono riportati gli elenchi di codice per questo esempio.
C#
using System;
using System.Data;
using System.Data.Sql;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using Microsoft.SqlServer.Server;
public sealed class DataAccessDemo
{
private DataAccessDemo()
{
}
/// <summary>
/// Simple example to send a message to the client.
/// </summary>
public static void SendMessage(string msg)
{
SqlContext.Pipe.Send("Message from server: " + msg);
}
/// <summary>
/// Simple example of performing data access within
/// a function
/// </summary>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction(DataAccess = Microsoft.SqlServer.Server.DataAccessKind.Read)]
public static string ReportSqlVersion()
{
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
//create a command from the current context
SqlCommand cmd = conn.CreateCommand();
//execute something
cmd.CommandText = "select @@version";
conn.Open();
//return results as scalar
return (string)cmd.ExecuteScalar();
}
}
/// <summary>
/// Create a result set on the fly and send it to the client.
/// </summary>
public static void SendTransientResultSet()
{
//create the metadata for the columns
Microsoft.SqlServer.Server.SqlMetaData[] columnSchema
= new Microsoft.SqlServer.Server.SqlMetaData[] {
new Microsoft.SqlServer.Server.SqlMetaData("stringcol", SqlDbType.NVarChar, 128)
};
//create a record based on that metadata
SqlDataRecord newRecord = new SqlDataRecord(columnSchema);
//populate it
newRecord.SetString(0, "Hello World!");
//send it
SqlContext.Pipe.Send(newRecord);
}
/// <summary>
/// Execute a command and send the results to the client directly.
/// </summary>
public static void ExecuteToClient()
{
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "select @@version";
conn.Open();
SqlContext.Pipe.ExecuteAndSend(cmd);
}
}
/// <summary>
/// Execute a command and send the resultig reader to the client
/// </summary>
public static void SendReaderToClient()
{
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "select @@version";
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
try
{
SqlContext.Pipe.Send(rdr);
}
finally
{
rdr.Close();
}
}
}
};
Visual Basic
Imports Microsoft.SqlServer.Server
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections
Imports System.Data
Imports System.Data.Sql
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
Imports System.Diagnostics
Partial Public NotInheritable Class DataAccessDemo
Private Sub New()
End Sub
''' <summary>
''' Simple example of performing data access within a function
''' </summary>
''' <returns></returns>
<SqlFunction(DataAccess:=DataAccessKind.Read)> _
Public Shared Function ReportSqlVersion() As SqlString
Using conn As New SqlConnection("context connection=true")
'create a command from the current context
Dim cmd As SqlCommand = conn.CreateCommand()
'execute something
cmd.CommandText = "SELECT @@VERSION"
conn.Open()
'return results as scalar
Return CType(cmd.ExecuteScalar(), String)
End Using
End Function
''' <summary>
''' Simple example to send a message to the client.
''' </summary>
Public Shared Sub SendMessage(ByVal msg As String)
SqlContext.Pipe.Send(("Message from server: " & msg))
End Sub
''' <summary>
''' Create a result set on the fly and send it to the client.
''' </summary>
Public Shared Sub SendTransientResultSet()
'create the metadata for the columns
Dim columnSchema() As Microsoft.SqlServer.Server.SqlMetaData _
= {New SqlMetaData("stringcol", SqlDbType.NVarChar, 128)}
'create a record based on that metadata
Dim newRecord As New SqlDataRecord(columnSchema)
'populate it
newRecord.SetString(0, "Hello World!")
'send it
SqlContext.Pipe.Send(newRecord)
End Sub
''' <summary>
''' Execute a command and send the results to the client directly.
''' </summary>
Public Shared Sub ExecuteToClient()
Using conn As New SqlConnection("context connection=true")
Dim cmd As SqlCommand = conn.CreateCommand()
cmd.CommandText = "SELECT @@VERSION"
conn.Open()
SqlContext.Pipe.ExecuteAndSend(cmd)
End Using
End Sub
''' <summary>
''' Execute a command and send the resulting reader to the client
''' </summary>
Public Shared Sub SendReaderToClient()
Using conn As New SqlConnection("context connection=true")
Dim cmd As SqlCommand = conn.CreateCommand()
cmd.CommandText = "SELECT @@VERSION"
conn.Open()
Dim rdr As SqlDataReader = cmd.ExecuteReader()
Try
SqlContext.Pipe.Send(rdr)
Finally
rdr.Close()
End Try
End Using
End Sub
End Class
Si tratta del Transact-SQL script di installazione (Install.sql), che distribuisce l'assembly e crea le stored procedure e la funzione richieste da questo esempio.
USE AdventureWorks;
GO
IF EXISTS (SELECT * FROM sys.procedures WHERE name = N'SendMessage')
DROP PROCEDURE SendMessage;
GO
IF EXISTS (SELECT * FROM sys.procedures WHERE name = N'SendTransientResultSet')
DROP PROCEDURE SendTransientResultSet;
GO
IF EXISTS (SELECT * FROM sys.procedures WHERE name = N'ExecuteToClient')
DROP PROCEDURE ExecuteToClient;
GO
IF EXISTS (SELECT * FROM sys.procedures WHERE name = N'SendReaderToClient')
DROP PROCEDURE SendReaderToClient;
GO
IF EXISTS (SELECT * FROM sys.objects WHERE name = N'ReportSqlVersion' and (type = 'FS' or type = 'FT'))
DROP FUNCTION [ReportSqlVersion];
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE name = N'InProcDA') DROP ASSEMBLY InProcDA;
GO
DECLARE @SamplesPath nvarchar(1024)
-- You may need to modify the value of the this variable if you have installed the sample someplace other than the default location.
set @SamplesPath = N'C:\MySample\'
CREATE ASSEMBLY InProcDA FROM @SamplesPath + 'InProcDA.dll'
WITH permission_set = SAFE;
GO
CREATE PROCEDURE [SendMessage] @msg nvarchar(4000)
AS
EXTERNAL NAME [InProcDA].[DataAccessDemo].[SendMessage];
GO
CREATE FUNCTION [ReportSqlVersion]() RETURNS nvarchar(4000)
AS EXTERNAL NAME [InProcDA].[DataAccessDemo].[ReportSqlVersion];
GO
CREATE PROCEDURE [SendTransientResultSet]
AS
EXTERNAL NAME [InProcDA].[DataAccessDemo].[SendTransientResultSet];
GO
CREATE PROCEDURE [ExecuteToClient]
AS
EXTERNAL NAME [InProcDA].[DataAccessDemo].[ExecuteToClient];
GO
CREATE PROCEDURE [SendReaderToClient]
AS
EXTERNAL NAME [InProcDA].[DataAccessDemo].[SendReaderToClient];
GO
Il seguente Transact-SQL (test.sql) verifica l'esempio esercitando le stored procedure e la funzione definite in questo esempio.
USE AdventureWorks;
GO
-- send a message to the client
EXEC SendMessage N'This is a test message.';
-- exec a function that does data access
SELECT dbo.ReportSqlVersion();
-- exec the proc that sends a result set to the client
EXEC SendTransientResultSet;
EXEC ExecuteToClient;
EXEC SendReaderToClient;
USE master;
GO
L'Transact-SQL seguente rimuove l'assembly, la funzione e le stored procedure dal database.
USE AdventureWorks
GO
IF EXISTS (SELECT * FROM sys.procedures WHERE name = N'SendMessage')
DROP PROCEDURE SendMessage;
GO
IF EXISTS (SELECT * FROM sys.procedures WHERE name = N'SendTransientResultSet')
DROP PROCEDURE SendTransientResultSet;
GO
IF EXISTS (SELECT * FROM sys.procedures WHERE name = N'ExecuteToClient')
DROP PROCEDURE ExecuteToClient;
GO
IF EXISTS (SELECT * FROM sys.procedures WHERE name = N'SendReaderToClient')
DROP PROCEDURE SendReaderToClient;
GO
IF EXISTS (SELECT * FROM sys.objects WHERE name = N'ReportSqlVersion' and (type = 'FS' or type = 'FT'))
DROP FUNCTION [ReportSqlVersion];
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE name = N'InProcDA') DROP ASSEMBLY InProcDA;
GO
Vedere anche
Scenari di utilizzo ed esempi per l'integrazione con CLR (Common Language Runtime)