Utilizar objetos COM y .NET desde MS SQL
 

Fecha: 28/Mar/2005 (24 de Marzo de 2005)
Autor: Miguel Muñoz Serafín, mmunoz@msm-networking.com

 


Este artículo muestra como utilizar en MS SQL un objeto COM y .NET. Las versiones de SQL 7 y SQL 2000 no soportan el uso de componentes .NET por lo cual para utilizar un componente .NET debemos crear y registrar el archivo de interoperabilidad (.tlb). Para crear el archivo de interoperabilidad y registrarlo en el sistema podemos utilizar la herramienta Regasm.exe que viene con Visual Studio o en el SDK del Net Framework. La sintáxis del Regasm es:

Regasm MiDLLNET.dll /tlb

La otra opción para crear y registrar un componente como COM en VB.NET es crear un proyecto (Class Library) y agregar un archivo nuevo Com Class. Al agregar el archivo Com Class se agregan automáticamente los métodos y atributos necesarios para que nuestra clase pueda ser utilizada como componente COM. Este es un ejemplo de lo que se vería después de agregar el Com Class:

<ComClass(ComClass.ClassId, ComClass.InterfaceId, ComClass.EventsId)> _
Public Class ComClass

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "A3BA0854-EE34-495B-8C27-75F4928A6C35"
    Public Const InterfaceId As String = "C4106BD0-D598-45D6-9D77-01E92077CC05"
    Public Const EventsId As String = "18691258-A420-4883-95D2-4A0C31D4A13D"
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub
End Class

El siguiente paso para continuar con el ejemplo es agregar las propiedades o métodos a nuestra clase. Para este ejemplo agregaré una propiedad y 3 métodos. La clase completa quedaría así:

<ComClass(ComClass.ClassId, ComClass.InterfaceId, ComClass.EventsId)> _
Public Class ComClass

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "A3BA0854-EE34-495B-8C27-75F4928A6C35"
    Public Const InterfaceId As String = "C4106BD0-D598-45D6-9D77-01E92077CC05"
    Public Const EventsId As String = "18691258-A420-4883-95D2-4A0C31D4A13D"
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub
    'Declaramos una propiedad para ejemplo
    Dim mRadio As Integer
    Public Property Radio() As Integer
        Get
            Return mRadio
        End Get
        Set(ByVal Value As Integer)
            mRadio = Value
        End Set
    End Property
    'Un método que recibe un argumento y regresa un valor
    Public Function PerimetroCirculo(ByVal radio As Single)
        Return System.Math.PI * radio * 2
    End Function
    'Un método que no recibe argumentos y regresa un valor
    Public Function AreaCirculo()
        Return System.Math.PI * mRadio * mRadio
    End Function
    'Un método que no recibe argumentos y no regresa valor
    Public Sub GeneraRadioAleatorio()
        mRadio = Rnd()
    End Sub
End Class

Al compilar este proyecto automáticamente se generará el archivo TLB y se registrará en el Registro de Windows.

En caso de tener un componente COM lo único que tenemos que hacer es registrarlo con la herramienta del sistema operativo Regsvr32.exe. La sintáxis sería:

Regsvr32 MiDLLCom.dll

Hasta este momento asumimos que el componente NET o COM ya esta registrado. El siguiente paso es utilizarlos desde SQL. Existen procedimientos en SQL que permiten utilizar componentes COM desde SQL que implementen la interface IDispatch. Actualmente SQL 7 o SQL 2000 solo soportan componentes COM. No soportan componentes .NET. Yukon ya soportará componentes .NET.

El procedimiento es relativamente sencillo:

  1. Crear el objeto con sp_OACreate
  2. Obtener el valor de una propiedad con sp_OAGetProperty
  3. Asignar el valor a una propiedad con sp_OASetProperty
  4. Llamar a un método con sp_OAMethod
  5. Obtiener el último error con sp_OAGetErrorInfo
  6. Destruir el objeto con sp_OADestroy

Pueden encontrar más información y ejemplos en la ayuda de SQL (Books Online) acerca de cada uno de estos procedimientos.

Para probar nuestra clase podemos utilizar en Analizador de Consultas (Query Analyzer) y escribir el siguiente script:

/* Este script muestra el uso de un componente COM desde SQL */

-- Variables utilizadas en el script
DECLARE @ValorDeRegreso INT
DECLARE @com INT
DECLARE @OrigenDelError VARCHAR(8000)
DECLARE @DescripcionDelError VARCHAR(8000)
DECLARE @Resultado FLOAT

-- Crear una instancia del componente
EXEC @ValorDeRegreso = sp_OACreate 'comnetvb.comClass', @com OUTPUT
IF (@ValorDeRegreso <> 0) -- Preguntar por algún error
BEGIN
   EXEC sp_OAGetErrorInfo @com, @OrigenDelError OUTPUT, @DescripcionDelError OUTPUT
   SELECT [Origen del error] = @OrigenDelError, [Descripcion] = 'Error al crear el componente COM. ' + @DescripcionDelError
   RETURN
END


-- Llama al método del COM con parametros. El método COM regresa un float
EXEC @ValorDeRegreso = sp_OAMethod @com, 'PerimetroCirculo', @Resultado OUTPUT, 5
IF (@ValorDeRegreso <> 0)
BEGIN
   EXEC sp_OAGetErrorInfo @com, @OrigenDelError OUTPUT, @DescripcionDelError OUTPUT
   SELECT [Origen del error] = @OrigenDelError, [Descripcion] =  @DescripcionDelError
   RETURN
END
-- Imprime el resultado
SELECT [Llamada al método con parámetros] = @resultado

-- Establece el valor de una propiedad
EXEC @ValorDeRegreso = sp_OASetProperty @com, 'Radio', 5
IF (@ValorDeRegreso <> 0)
BEGIN
   EXEC sp_OAGetErrorInfo @com, @OrigenDelError OUTPUT, @DescripcionDelError OUTPUT
   SELECT [Origen del error] = @OrigenDelError, [Descripcion] =  @DescripcionDelError
   RETURN
END
-- Obtiene el valor de una propiedad
EXEC @ValorDeRegreso = sp_OAGetProperty @com, 'Radio', @Resultado OUTPUT
IF (@ValorDeRegreso <> 0)
BEGIN
   EXEC sp_OAGetErrorInfo @com, @OrigenDelError OUTPUT, @DescripcionDelError OUTPUT
   SELECT [Origen del error] = @OrigenDelError, [Descripcion] =  @DescripcionDelError
   RETURN
END
-- Imprime el resultado
SELECT [Valor establecido a una propiedad] = @resultado


-- Llama al método del COM sin parametros. El método COM regresa un float
EXEC @ValorDeRegreso = sp_OAMethod @com, 'AreaCirculo', @Resultado OUTPUT
IF (@ValorDeRegreso <> 0)
BEGIN
   EXEC sp_OAGetErrorInfo @com, @OrigenDelError OUTPUT, @DescripcionDelError OUTPUT
   SELECT [Origen del error] = @OrigenDelError, [Descripcion] =  @DescripcionDelError
   RETURN
END
-- Imprime el resultado
SELECT [Llamada al método COM sin parametros] = @resultado

-- Llama al método del COM sin parametros. El método COM no regresa valor.
EXEC @ValorDeRegreso = sp_OAMethod @com, 'GeneraRadioAleatorio'
IF (@ValorDeRegreso <> 0)
BEGIN
   EXEC sp_OAGetErrorInfo @com, @OrigenDelError OUTPUT, @DescripcionDelError OUTPUT
   SELECT [Origen del error] = @OrigenDelError, [Descripcion] =  @DescripcionDelError
   RETURN
END

-- Destruir la referencia
EXEC sp_OADestroy @com

/* Fin del script */

Espero la información les sea útil y espero sus comentarios.

Saludos!!!
 

  



ir al índice