SQLServerCentral Article

Calling COM From T-SQL

,

Introduction

If you need to store data or retrieve stored in SQL Server, no second thought is necessary and you will go for T-SQL. However, how can you integrate T-SQL with external applications? For example if you need to integrate SQL Server with Microsoft Exchange Server or MS Word, how are you going to accomplish this? There are seven extended stored procedures to call external applications like DLLs.

Stored ProcedureDescription
sp_OACreate Creates an instance of the OLE object on an instance

of Microsoft SQL Server

sp_OADestroy Destroys a created OLE object
sp_OAGetErrorInfo Obtains OLE Automation error information
sp_OAGetProperty Gets a property value of an OLE object.
sp_OASetProperty Sets a property of an OLE object to a new value
sp_OAMethod Calls a method of an OLE object
sp_OAStop Stops the server-wide OLE Automation stored procedure execution environment

Source :SQL Server BOL

Implementation

Let us take a simple example to implement this. Our requirement will be accessing a third party dll inside a table trigger.

From the above table, user will enter "a" and "b" and the"sum" is needed to have the results of "a + b", which is calculated by using a DLL function. Yes I know you can do this simple update statement. However, you will understand that I am going to do a simple demo using a DLL. In addition, users will enter ComString and that needs to be written to a text file.

The following are the two functions which are developed in VB. AddTwoNumbers will give you the sum of the two inputs while the WriteToFile will write to text file called COMTEXT.txt with the value given by the parameter. Basically one function have input,output while the other has only an input.

Public Function AddTwoNumbers (i As Integer, j As 
Integer) As Integer
    AddTwoNumbers = (i + j)
End Function
 Public Sub WriteToFile(strText As String)
    Dim fso As New FileSystemObject
    Dim ts As TextStream
    Set ts = fso.CreateTextFile("C:\COMTEST.txt")
    ts.WriteLine (strText)
    ts.Close
End Sub
CREATE  TRIGGER [trgcom] ON [dbo].[TRIGGERCOM] 
FOR INSERT, UPDATE
AS
DECLARE @retVal smallint
DECLARE @comHandle INT
DECLARE @errorSource VARCHAR(8000)
DECLARE @errorDescription VARCHAR(8000)
DECLARE @retString VARCHAR(100)
DECLARE @retTot smallint
DECLARE @nval1 smallint
DECLARE @nval2 smallint
DECLARE @ID int
 
Select @nval1 = a, @nval2 = b,@ID=id,@retString = t 
from inserted 
EXEC @retVal = sp_OACreate ' TestClass.TestClass', @comHandle 
OUTPUT, 4
IF (@retVal <> 0)
BEGIN
            
-- Error Handling 
            
EXEC sp_OAGetErrorInfo @comHandle, @errorSource OUTPUT, @errorDescription 
OUTPUT
            
SELECT [Error Source] = @errorSource, [Description] = @errorDescription
            
RETURN
END
-- Call a method into the component
EXEC @retVal = sp_OAMethod @comHandle, 'WriteToFile',NULL,  
@retString
IF (@retVal <> 0)
BEGIN
            
-- Error Handling 
            
EXEC sp_OAGetErrorInfo @comHandle, @errorSource OUTPUT, @errorDescription 
OUTPUT
            
SELECT [Error Source] = @errorSource, [Description] = @errorDescription
            
RETURN
END
-- Call a method into the component
EXEC @retVal = sp_OAMethod @comHandle, 'AddTwoNumbers',@retTot 
OUTPUT, @nval1,@nval2 
IF (@retVal <> 0)
BEGIN
               
-- Error Handling 
            
EXEC sp_OAGetErrorInfo @comHandle, @errorSource OUTPUT, @errorDescription 
OUTPUT
            
SELECT [Error Source] = @errorSource, [Description] = @errorDescription
            
RETURN
END
-- Update table
update TRIGGERCOM  set [sum] = @rettot where id = @id
-- Release the reference to the COM object
EXEC sp_OADestroy @comHandle

Now we will see what the above code does.

sp_OACreate will create an instance of a the DLL to SQL Server. If it is successfully created output, the will be 0. If it is non-zero then you can send it to OAGetErrorInfo and get the error messages. sp_OAMethod is to call the method of the DLL. In first case you are calling the method WriteToFile which does not have any returned values. The last parameter of sp_OACreate must be either of 1,4 or 5. it specifies the execution context in which the newly created OLE object runs. If specified, this value must be one of the following:

1 = In-process (.dll) OLE server only
4 = Local (.exe) OLE server only
5 = Both in-process and local OLE server allowed

If not specified, the default value is 5.

If an in-process OLE server is allowed (by using a context value of 1 or 5 or by not specifying a context value), it has access to memory and other resources owned by SQL Server. An in-process OLE server may damage SQL Server memory or resources and cause unpredictable results, such as a SQL Server access violation.

When you specify a context value of 4, a local OLE server does not have access to any SQL Server resources, and it cannot damage SQL Server memory or resources.

(From BOL)

sp_OAMethod @comHandle, 'WriteToFile',NULL,

@retString

@comHandle is the handle to the object which is the

output that you got from the sp_OACreate.

sp_OAMethod @comHandle, 'AddTwoNumbers',@retTot OUTPUT,

@nval1,@nval2

In this case you can see that two parameters at the end

of the function call. Finally sp_OADestroy will destroy a created OLE object

in the SQL Server. After that, T-SQL is used to update the tables.

More Examples

Let us see how we can use this further. In MS Word there are many properties, it is much better to know whether that property is available before doing an operation with regards to that specified property. You can check properties likeMathCoProcessorAvailable, MapiAvailable. You can find the MSWord properties

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbawd11/html/woobjApplication1_HV05209908.asp

What if you need to check spelling from SQL Server? Isn’t it useful to have this functionality from the SQL Server?

DECLARE @retVal int
DECLARE @comHandle  int
DECLARE @IsSpellingCorrect bit
DECLARE @errorSource VARCHAR(8000)
DECLARE @errorDescription VARCHAR(8000)
DECLARE @SpellWord varchar(255)
SET @SpellWord = 'Server'
EXEC @retVal = sp_OACreate 'Word.Application', @comHandle  OUT ,4
EXEC @retVal = sp_OAMethod @comHandle , 'CheckSpelling'
             , @IsSpellingCorrect OUT, @SpellWord
EXEC @retVal = sp_OADestroy @comHandle  
IF @retVal <> 0
 BEGIN           
EXEC sp_OAGetErrorInfo @comHandle, @errorSource OUTPUT, @errorDescription OUTPUT

SELECT [Error Source] = @errorSource, [Description] = @errorDescription
RETURN
 END 
Print @IsSpellingCorrect 

Above code will return you 1 if the @SpellWord is spelled correctly. You can create an stored procedure an use the word as a parameter.

You can print documents, create documents by the above methods. If you need the code for those functions drop me an email.

Other than the above there are more practical cases where you need this above automation scripts. For example if you need to communicate with the Windows services where you won’t find any SQL Server built-in methods, you can easily build an third party Activex DLL and call those methods from the SQL Server stored procedure.

Using 'CDO.Message', you can send emails from SQL Server. You can attach documents as well.

For More information you can visit http://support.microsoft.com/kb/152801/EN-US/

Conclusion

Basically, you can call whatever the method available in the OLE. This is very useful as you can integrate the other functionalities and making SQL Server a rich application platform.

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating