Compartir vía


Introducción a la integración de CLR

Se aplica a:SQL Server

En este artículo se proporciona información general sobre los espacios de nombres y las bibliotecas necesarios para compilar objetos de base de datos mediante la integración de SQL Server con Common Language Runtime (CLR) de .NET Framework. En el artículo también se muestra cómo escribir, compilar y ejecutar un procedimiento almacenado CLR pequeño escrito en C# y Visual Basic .NET.

Espacios de nombres necesarios

Los componentes necesarios para desarrollar objetos de base de datos CLR básicos se instalan con SQL Server. La funcionalidad de la integración CLR se expone en un ensamblado denominado System.Data.dll, que forma parte de .NET Framework. Este ensamblado se puede encontrar en la caché global de ensamblados (GAC) y en el directorio de .NET Framework. Normalmente, las herramientas de línea de comandos y Visual Studio agregan automáticamente una referencia a este ensamblado, por lo que no es necesario agregarlo manualmente.

El System.Data.dll contiene los espacios de nombres siguientes, que son necesarios para compilar objetos de base de datos CLR:

  • System.Data
  • System.Data.Sql
  • Microsoft.SqlServer.Server
  • System.Data.SqlTypes

Sugerencia

Se admite la carga de objetos de base de datos CLR en Linux, pero deben compilarse con .NET Framework (la integración de CLR de SQL Server no admite .NET Core o .NET 5 y versiones posteriores). Además, los ensamblados CLR con el conjunto de permisos EXTERNAL_ACCESS o UNSAFE no se admiten en Linux.

Escribir un procedimiento almacenado "Hola mundo"

Copie y pegue el siguiente código de C# o Visual Basic .NET en un editor de texto y guárdelo en un archivo denominado helloworld.cs o helloworld.vb.

using System;
using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;

public class HelloWorldProc
{
    [Microsoft.SqlServer.Server.SqlProcedure]
    public static void HelloWorld(out string text)
    {
        SqlContext.Pipe.Send("Hello world!" + Environment.NewLine);
        text = "Hello world!";
    }
}

Este programa contiene un solo método estático en una clase pública. Este método usa dos clases nuevas, SqlContext y SqlPipe, para crear los objetos de base de datos administrados a fin de generar un mensaje de texto corto. El método también asigna la cadena "Hello world!" como valor de un parámetro out. Este método puede declararse como un procedimiento almacenado en SQL Server y, a continuación, ejecutarse del mismo modo que un procedimiento almacenado de Transact-SQL.

Compile este programa como una biblioteca, cárguelo en SQL Server y ejecútelo como un procedimiento almacenado.

Compile el procedimiento almacenado "Hello World"

SQL Server instala los archivos de redistribución de .NET Framework de forma predeterminada. Estos archivos incluyen csc.exe y vbc.exe, los compiladores de línea de comandos para programas .NET de C# y Visual Basic. Para compilar el ejemplo, debe modificar la variable de ruta de acceso para que apunte al directorio que contiene los archivos csc.exe o vbc.exe. Ésta es la ruta de instalación predeterminada de .NET Framework.

C:\Windows\Microsoft.NET\Framework\(version)

La versión incluye el número de versión del componente .NET Framework instalado. Por ejemplo:

C:\Windows\Microsoft.NET\Framework\v4.8.0

Una vez agregado el directorio .NET Framework a la ruta de acceso, puede compilar el procedimiento almacenado de ejemplo en un ensamblado con el siguiente comando. La opción /target permite compilarlo en un ensamblado.

Para los archivos de código fuente de C#:

csc /target:library helloworld.cs

Para los archivos de origen de .NET de Visual Basic:

vbc /target:library helloworld.vb

Estos comandos inician el compilador de .NET de C# o Visual Basic mediante la opción /target para especificar la creación de un archivo DLL de biblioteca.

Cargar y ejecutar el procedimiento almacenado "Hello World" en SQL Server

Una vez que el procedimiento de ejemplo se compila correctamente, puede probarlo en SQL Server. Para ello, abra SQL Server Management Studio y cree una nueva consulta, conectándose a una base de datos de prueba adecuada (por ejemplo, la base de datos de pruebaAdventureWorks2022).

La capacidad de ejecutar el código de Common Language Runtime (CLR) está establecida de forma predeterminada en OFF en SQL Server. El código CLR se puede habilitar mediante el procedimiento almacenado del sistema sp_configure. Para más información, consulte Habilitar la integración de CLR.

Es necesario crear el ensamblado para poder acceder al procedimiento almacenado. En este ejemplo, se supone que creó el ensamblado helloworld.dll en el directorio C:\. Agregue la siguiente instrucción Transact-SQL a su consulta.

CREATE ASSEMBLY helloworld from 'C:\helloworld.dll' WITH PERMISSION_SET = SAFE

Una vez creado el ensamblado, ahora podemos acceder al método HelloWorld mediante la instrucción CREATE PROCEDURE. Llamamos a nuestro procedimiento almacenado hello:

CREATE PROCEDURE hello
(@i NCHAR (25) OUTPUT)
AS EXTERNAL NAME helloworld.HelloWorldProc.HelloWorld;

Nota

En el ejemplo anterior, si la clase HelloWorldProc está dentro de un espacio de nombres (denominado MyNS), la última línea de la instrucción create procedure sería EXTERNAL NAME helloworld.[MyNS.HelloWorldProc].HelloWorld;.

Una vez creado el procedimiento, se puede ejecutar como un procedimiento almacenado normal escrito en Transact-SQL. Ejecute el siguiente comando:

DECLARE @J AS NCHAR (25);
EXECUTE hello @J OUTPUT;
PRINT @J;

Esta es la salida esperada.

Hello world!
Hello world!

Quite el ejemplo de procedimiento almacenado "Hello World"

Cuando haya terminado de ejecutar el procedimiento almacenado de ejemplo, puede quitar el procedimiento y el ensamblado de la base de datos de prueba.

En primer lugar, quite el procedimiento mediante el comando de drop procedure.

IF EXISTS (SELECT name
           FROM sysobjects
           WHERE name = 'hello')
    DROP PROCEDURE hello;

Una vez que se elimine el procedimiento, puede quitar el ensamblaje que contiene su código de ejemplo.

IF EXISTS (SELECT name
           FROM sys.assemblies
           WHERE name = 'helloworld')
    DROP ASSEMBLY helloworld;