Click here to monitor SSC
SQLServerCentral is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
 
 
 
        
Home       Members    Calendar    Who's On


Add to briefcase 12345»»»

Actual Reason to Use CLR Expand / Collapse
Author
Message
Posted Friday, May 11, 2007 7:39 AM


SSChampion

SSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampion

Group: General Forum Members
Last Login: Today @ 11:14 AM
Points: 11,884, Visits: 22,833

Steve created a forum, might as well use it...

The one question that none of the DBA's where I work have been able to answer is, why do we need CLR? What's it going to do for us that we couldn't do with TSQL or out in the application code? Has anyone come up with some good answers to this question?



----------------------------------------------------
"The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood..." Theodore Roosevelt
The Scary DBA
Author of: SQL Server 2008 Query Performance Tuning Distilled
and
SQL Server Execution Plans

Product Evangelist for Red Gate Software
Post #365107
Posted Saturday, May 12, 2007 4:41 PM


Say Hey Kid

Say Hey KidSay Hey KidSay Hey KidSay Hey KidSay Hey KidSay Hey KidSay Hey KidSay Hey Kid

Group: General Forum Members
Last Login: Friday, November 06, 2009 3:08 AM
Points: 685, Visits: 93

i think the purpose for the clr is to blur the divide between the database and the application program.




Everything you can imagine is real.

Post #365401
Posted Sunday, May 13, 2007 11:47 AM
Hall of Fame

Hall of FameHall of FameHall of FameHall of FameHall of FameHall of FameHall of FameHall of FameHall of Fame

Group: General Forum Members
Last Login: Today @ 6:38 AM
Points: 3,419, Visits: 14,163


Grant,
Microsoft is just joining the party because Oracle have been running Java runtime in memory since oracle 8i or 9i and a .NET runtime albeit out of process is in development so Microsoft needed to add the .NET runtime in SQL Server.  Another thing with LINQ coming in .NET 3.5, like XML before it what is a query could be anything.

 



Kind regards,
Gift Peddie
Post #365419
Posted Monday, May 14, 2007 12:07 AM


Ten Centuries

Ten CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen Centuries

Group: General Forum Members
Last Login: 2 days ago @ 3:10 PM
Points: 1,244, Visits: 859

CLR is there to allow you to do what you can not do in T-SQL. You should always prefer T-SQL over CLR when you can because it performs better.

Perhaps in the near future, the CLR implementation will be more refined, but until then, I suggest using it only when you must.





My blog: SQL Soldier
Twitter: @SQLSoldier
Microsoft Certified Master: SQL Server 2008
Program Manager: SQL Server Master Certification Program
Post #365481
Posted Monday, May 14, 2007 12:20 AM
Old Hand

Old HandOld HandOld HandOld HandOld HandOld HandOld HandOld Hand

Group: General Forum Members
Last Login: Thursday, September 11, 2008 4:03 AM
Points: 325, Visits: 36

I agree with Mr. or Mrs 500 you should always use TSQL when doing data manipulation using DML, you should consider CLR functions when ur not doing DML, but rather thing like string concatenation or string manipulations.

Post #365488
Posted Monday, May 14, 2007 2:14 AM


SSCertifiable

SSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiable

Group: General Forum Members
Last Login: Today @ 1:12 AM
Points: 6,627, Visits: 7,334

There is ofcourse the classic literature :

Using CLR Integration in SQL Server 2005 (http://msdn2.microsoft.com/en-us/library/ms345136.aspx)

http://www.programmersheaven.com/2/SQL-server-2005-school-lesson-6

Managed Code (CLR)

You should use managed code for creating database objects in the following situations:

ü      You require complex programmatic constructs or features such as object orientation to complete a task.

ü      You need to use the .NET Framework’s base class library to perform a task that is difficult or impossible with Transact-SQL.

ü           Your required functionality will be CPU-intensive.

 



Johan

Don't drive faster than your guardian angel can fly ...
but keeping both feet on the ground won't get you anywhere

- How to post Performance Problems
- How to post data/code to get the best help


- How to prevent a sore throat after hours of presenting ppt ?


"press F1 for solution", "press shift+F1 for urgent solution"


Need a bit of Powershell? How about this

Who am I ? Sometimes this is me but most of the time this is me
Post #365509
Posted Monday, May 14, 2007 3:42 AM


SSChampion

SSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampion

Group: General Forum Members
Last Login: Today @ 11:14 AM
Points: 11,884, Visits: 22,833

Yeah, I've read a lot of that stuff. I was just wondering if anyone had come up with a compelling, real-world, example of using CLR and getting more or better functionality out of it that works better/faster/stronger than simply running the same code on an application server or a client.

I have one, very small, example. Itzik Ben-Gan shows how to use CLR & common expressions available in .NET languages to clean all the parameters off of stored procedure calls in a trace file. It's nice, but it's hardly a good reason to run and spend time honing C# skills.



----------------------------------------------------
"The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood..." Theodore Roosevelt
The Scary DBA
Author of: SQL Server 2008 Query Performance Tuning Distilled
and
SQL Server Execution Plans

Product Evangelist for Red Gate Software
Post #365537
Posted Monday, May 14, 2007 10:25 AM
Forum Newbie

Forum NewbieForum NewbieForum NewbieForum NewbieForum NewbieForum NewbieForum NewbieForum Newbie

Group: General Forum Members
Last Login: Sunday, February 15, 2009 2:20 PM
Points: 4, Visits: 61
I have used the CLR and extended stored procedures for a couple of reasons.  They both are "Transaction related".  I have code that allows me to log SQL execution without being affected by a rollback.  The other is to do processing that was in a transaction where I needed to process external data while still having the ability to rollback the transaction if there was an error while doing so.
Post #365692
Posted Monday, May 14, 2007 12:20 PM
SSC-Enthusiastic

SSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-Enthusiastic

Group: General Forum Members
Last Login: Friday, July 06, 2007 3:11 AM
Points: 145, Visits: 1
As Itzik also pointed out the CLR comes in handy if for calculations; things that have nothing to do with database access, but nevertheless need to be done in the db and not on the client. Probably we will not benefit from this in stored procedures and triggers, but I can imagine it in UDFs and maybe there exists a business case for CLR datatypes.
We are using a financial database with check digits for standard codes like ISIN and SEDOL. We need to implement check constraints that enforce them. I have implemented them both in TSQL and vb.net. I tested the checks in a loop and here we see a significant improvement: depending on the algorithm, the .net version runs twice to three times as fast.

Algorithm times CLR TSQL Perc
Sedol 1000 46 80 57,50
10000 376 810 46,42
100000 3726 8160 45,66

Isin 1000 60 156 38,46
10000 534 1826 29,24
100000 5380 16380 32,84

Of course for all data access I would certainly use TSQL.
The code: (the explanation of the algorithms can be found at Wikipedia.org)

go
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Jan DV
-- Create date: 8/05/2007
-- Description: Check validity of an SEDOL code
-- Examples: 6870401, B06G5D9, 5330047
-- dbo.fn_IIM_IsValidSedol('B06G5D9') = 1
-- dbo.fn_IIM_IsValidSedol('6870401') = 1
-- =============================================
IF EXISTS(SELECT * FROM sys.objects WHERE name = 'fn_IIM_IsValidSedol' AND type = 'FN')
DROP FUNCTION dbo.fn_IIM_IsValidSedol
GO

CREATE FUNCTION fn_IIM_IsValidSedol
(
-- ISIN code to be verified
@sSedol char(7)
)
RETURNS int
AS
BEGIN

-- weight factor: 131739
DECLARE @sArrWeighting char(6)
DECLARE @nPos smallint
DECLARE @n smallint
DECLARE @nSum int
DECLARE @nCheckDigit smallint
DECLARE @nReturn int

-- check if datalength = 7
IF IsNumeric(RIGHT(@sSedol,1)) = 1
SELECT @nCheckDigit = CONVERT(smallint,RIGHT(@sSedol,1))
ELSE
SELECT @nCheckDigit = -1

SELECT @sSedol = UPPER(@sSedol), @nPos = 1, @nSum = 0
SELECT @sArrWeighting = '131739'

WHILE @nPos < 7
BEGIN
SELECT @n =
CASE WHEN ISNUMERIC(SUBSTRING(@sSedol,@nPos,1)) = 1
THEN CONVERT(smallint,SUBSTRING(@sSedol,@nPos,1))
ELSE ASCII(SUBSTRING(@sSedol,@nPos,1)) - 55
END

SELECT @nSum = @nSum + (@n * CONVERT(int,SUBSTRING(@sArrWeighting,@nPos,1)))
SELECT @nPos = @nPos + 1

END

-- return if checkdigit is correct or not
IF ((10 - (@nSum % 10)) = @nCheckDigit) SELECT @nReturn = 1 ELSE SELECT @nReturn = 0
RETURN @nReturn
END

go
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Jan DV
-- Create date: 23/04/2007
-- Description: Check validity of an ISIN code
-- Examples: US0378331005, AU0000XVGZA3
-- dbo.fn_IIM_IsValidIsin('AU0000XVGZA3') = 1
-- dbo.fn_IIM_IsValidIsin('AU0000XVGZA3') = 1
-- =============================================
IF EXISTS(SELECT * FROM sys.objects WHERE name = 'fn_IIM_IsValidIsin' AND type = 'FN')
DROP FUNCTION dbo.fn_IIM_IsValidIsin
GO

CREATE FUNCTION fn_IIM_IsValidIsin
(
-- ISIN code to be verified
@sIsin char(12)
)
RETURNS int
AS
BEGIN

DECLARE @nCheckDigit smallint
DECLARE @nCounter smallint
DECLARE @nASCII smallint
DECLARE @sArrNumbers varchar(24)
DECLARE @sChar char(1)
DECLARE @nEven smallint
DECLARE @nTotal int

SELECT @nCheckDigit = CONVERT(smallint,RIGHT(@sIsin,1))


-- convert chars to numeric, with an offset of 10
SELECT @sIsin = Upper(@sIsin), @nCounter = 1, @sArrNumbers = ''
WHILE @nCounter < 12 -- do not include the checkdigit
BEGIN
SELECT @sChar = SUBSTRING(@sIsin, @nCounter, 1)
SELECT @nASCII = ASCII(@sChar)

IF @nASCII > 64 AND @nASCII < 91
SELECT @sArrNumbers = @sArrNumbers + CONVERT(varchar(2), @nASCII - 55) -- offset 10
ELSE
SELECT @sArrNumbers = @sArrNumbers + @sChar

SELECT @nCounter = @nCounter + 1
END

-- if odd, then double the first numbers; else 2nd list.
SELECT @nEven = 1 - (DATALENGTH(@sArrNumbers) % 2)

SELECT @nCounter = 1, @nTotal = 0
WHILE @nCounter <= DATALENGTH(@sArrNumbers)
BEGIN

-- if a number has 2 digits, sum them seperately. Multiply the correct column. @nEven is used to shift the multiplication position.
SELECT @nTotal = @nTotal +
(((CONVERT(int, SUBSTRING(@sArrNumbers, @nCounter, 1)) * (((@nCounter + @nEven) % 2) + 1)) % 10) +
ROUND(CONVERT(int, SUBSTRING(@sArrNumbers, @nCounter, 1)) * (((@nCounter + @nEven) % 2) + 1) / 10,0))

SELECT @nCounter = @nCounter + 1

END

-- return if checkdigit is correct or not
IF ((10 - (@nTotal % 10)) = @nCheckDigit) SELECT @nTotal = 1 ELSE SELECT @nTotal = 0
RETURN @nTotal
END

The CLR code:

Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server

Partial Public Class UserDefinedFunctions

_
Public Shared Function fn_IIM_CLRCheckSedol(ByVal sSedol As SqlString) As SqlBoolean

Dim arWeighting() As Byte = {1, 3, 1, 7, 3, 9}
Dim arSedol(5) As Byte
Dim nCheckDigit As Byte
Dim nTotal As Byte = 0

Try
If IsNumeric(sSedol.ToString) And Len(sSedol.ToString) = 7 Then

Dim n As Byte
For n = 1 To 6
arSedol(n - 1) = CByte(Mid(sSedol.ToString, n, 1))
Next
nCheckDigit = CByte(Mid(sSedol.ToString, 7, 1))

' Sum the result
For n = 0 To 5
nTotal += (arSedol(n) * arWeighting(n))
Next

'Return true if there is a match with the checkdigit
Return (10 - (nTotal Mod 10)) = nCheckDigit

Else : Return False 'Sedol passed should be numerical
End If
Catch
Return False
End Try

End Function
End Class

Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server

Partial Public Class UserDefinedFunctions
_
Public Shared Function fn_IIM_CLRCheckISIN(ByVal spIsin As SqlString) As SqlBoolean

If Len(spIsin.ToString) = 12 Then

Dim arrNumbers(22) As Integer 'ISIN is 12 char, 22 is the max size the array can become because there is one checkdigit
Dim sIsin As String
Dim nPos As Integer = 1
Dim nArrPos As Integer = 0
Dim sChar As String
Dim nValue As Integer = 0
Dim nOdd As Integer = 0
Dim nCheckDigit As Integer

Try

'Make sure that all ascii values are in upper range
sIsin = spIsin.ToString.ToUpper
nCheckDigit = CInt(Mid(sIsin, 12, 1))
For nPos = 1 To 11
sChar = Mid(sIsin, nPos, 1)

If IsNumeric(sChar) Then
arrNumbers(nArrPos) = CInt(sChar)
nArrPos += 1
Else
nValue = Asc(sChar) - 55
If nValue > 9 Then
arrNumbers(nArrPos) = (nValue \ 10)
arrNumbers(nArrPos + 1) = (nValue Mod 10)
nArrPos += 2
Else
arrNumbers(nArrPos) = nValue
nArrPos += 1
End If
End If
Next

'If # elements are odd, multiply odd values by 2 else even values.
nOdd = (nArrPos Mod 2)

For nPos = 0 To (nArrPos - 1)
arrNumbers(nPos) = arrNumbers(nPos) * (((nPos + nOdd) Mod 2) + 1)
Next

' Add up the individual digits
nValue = 0
For nPos = 0 To nArrPos - 1
If arrNumbers(nPos) < 10 Then
nValue += arrNumbers(nPos)
Else
nValue += (arrNumbers(nPos) \ 10)
nValue += (arrNumbers(nPos) Mod 10)
End If
Next

'Return True if checkdigit matches
Return (10 - (nValue Mod 10) = nCheckDigit)
Catch
Return False
End Try
Else
Return False 'Lenghth of ISIN code is not 12
End If

End Function
End Class

And the test:
DECLARE @dStart datetime
DECLARE @dStop datetime
DECLARE @n int
DECLARE @bResult bit

SELECT @dStart = Getdate()
SELECT @n=0
WHILE @n < 100000
BEGIN
SELECT @bResult= dbo.fn_IIM_CLRCheckSedol('0263494')
SELECT @bResult= dbo.fn_IIM_CLRCheckSedol('A263494')
SELECT @n = @n + 1
END
SELECT @dStop = getdate()

SELECT datediff(ms, @dStart, @dStop) -- 46 ms in CLR version
--- Test ISIN
DECLARE @dStart datetime
DECLARE @dStop datetime
DECLARE @n int
DECLARE @bResult bit

SELECT @dStart = Getdate()
SELECT @n=0
WHILE @n < 100000
BEGIN
SELECT @bResult= dbo.fn_IIM_IsValidIsin('BE0003788057')
SELECT @bResult= dbo.fn_IIM_IsValidIsin('AU0000XVGZA3')
SELECT @n = @n + 1
END
SELECT @dStop = getdate()

SELECT datediff(ms, @dStart, @dStop)
Post #365721
Posted Tuesday, May 15, 2007 12:10 AM


Ten Centuries

Ten CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen Centuries

Group: General Forum Members
Last Login: 2 days ago @ 3:10 PM
Points: 1,244, Visits: 859

The lead developer at my former company had downloaded some canned code off of some website that used the CLR to access the Windows API for time zone information which gave us nice little functions that converted customer's time zones to our local time and back.

They were nice little functions that slowed down the entire system because every time someone converted a time, they had to access the CLR which in turn accessed the Windows API. It also caused a memory leak when the system was under a heavy load that would silently kill connections and then eventually restart the SQL Service.

I replaced it with a process that imports the same time zone info using xp_instance_reg_read once a day at 4 AM and then uses the data in the TimeZones table to make the same conversions without slowing anything down and without causing a memory leak.

There's one real life example where the CLR should not have been used.





My blog: SQL Soldier
Twitter: @SQLSoldier
Microsoft Certified Master: SQL Server 2008
Program Manager: SQL Server Master Certification Program
Post #365850
« Prev Topic | Next Topic »

Add to briefcase 12345»»»

Permissions Expand / Collapse