<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>nlsimmons.com &#187; SQL CLR</title>
	<atom:link href="http://nlsimmons.com/?cat=6&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://nlsimmons.com</link>
	<description>Professional Blog &#38; Online Resume</description>
	<lastBuildDate>Wed, 10 Jun 2015 15:02:01 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.2.2</generator>
	<item>
		<title>Signing CLR Assemblies</title>
		<link>http://nlsimmons.com/?p=181</link>
		<comments>http://nlsimmons.com/?p=181#comments</comments>
		<pubDate>Mon, 06 Dec 2010 18:04:40 +0000</pubDate>
		<dc:creator><![CDATA[]]></dc:creator>
				<category><![CDATA[Permissions]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQL CLR]]></category>

		<guid isPermaLink="false">http://nlsimmons.com/SQLScraps/?p=181</guid>
		<description><![CDATA[So you want to load a CLR assembly into SQL Server.  What&#8217;s that you say?  You DONT want to set&#8230;]]></description>
				<content:encoded><![CDATA[            <script type="text/javascript" src="http://nlsimmons.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushSql.js"></script>
<p>So you want to load a CLR assembly into SQL Server.  What&#8217;s that you say?  You DONT want to set your database to TRUSTWORTHY?  Well look no further, there is a much more secure alternative to the old TRUSTWORTHY fallback: sign your assemblies with a secure certificate.</p>
<p>While this sounds like a walk in the park, it&#8217;s not very straight-forward.  In this post I will walk you through the steps necessary to get up and running with a signed assembly.  First you&#8217;ll need some additional tools.  You&#8217;ll need the makecert.exe tool, which is part of the Microsoft Windows SDK.  Also needed are the signtool and pvk2pfx tool, both of which are also part of the SDK.  You can download the Windows SDK here: <a href="http://go.microsoft.com/fwlink/?linkid=84091">http://go.microsoft.com/fwlink/?linkid=84091</a>.</p>
<p>Once you&#8217;ve downloaded and installed the SDK, you&#8217;re ready to begin.  First, create the root authority certificate:<br />
<pre class="brush: sql">makecert -sv SignRoot.pvk -cy authority -r signroot.cer -n &quot;CN=Cert Authority&quot;</pre></p>
<p>Once you&#8217;ve created this certificate, use it to create an additional certificate and private key pair.  This is what will be loaded into SQL server.  It is also what you will use to sign compiled DLL files.<br />
<pre class="brush: sql">makecert -m 360 -n &quot;CN=Signing Cert&quot; -iv signroot.pvk -ic signroot.cer -cy end -pe -sv signcert.pvk signcert.cer
</pre></p>
<p>Now convert this certificate into a PFX file for signing assemblies:<br />
<pre class="brush: sql">pvk2pfx -pvk signcert.pvk -spc signcert.cer -pfx signcert.pfx</pre></p>
<p>Once you have the PFX file, you can use it to sign assemblies:<br />
<pre class="brush: sql">signtool sign /f signcert.pfx &quot;YOUR_DLL_HERE&quot;</pre></p>
<p>Load the certificate file created above into SQL Server. Be sure to use the .cer file:<br />
<pre class="brush: sql">USE [master];
GO

CREATE CERTIFICATE CLRCertificate
FROM FILE = 'signcert.cer'
WITH PRIVATE KEY (
	  FILE = 'signcert.pvk'
	, DECRYPTION BY PASSWORD = 'password'
	, ENCRYPTION BY PASSWORD = 'password'
)
</pre></p>
<p>Now that the certificate has been loaded into SQL Server, you need to create a login from that certificate.  This login will need to have the necessarey assembly permissions (unsafe, external_access).<br />
<pre class="brush: sql">CREATE LOGIN AssemblyLoader FROM CERTIFICATE CLRCertificate
REVOKE connect sql FROM AssemblyLoader 
GRANT external access assembly TO AssemblyLoader 
GRANT unsafe assembly TO AssemblyLoader 
</pre><br />
By creating a certificate-based login that has the unsafe assembly and external_access assembly permissions, you need not grant any other login these permissions.  When you go to load a signed assembly, SQL Server sees that there is a login associated with the signing certificate and that the login has the necessary permissions to load assemblies of any permission level.  </p>
<p>There you have it, the assembly is successfully loaded into SQL Server without compromising security by using the TRUSTWORTHY flag.  Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://nlsimmons.com/?feed=rss2&#038;p=181</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Non-Trivial SQL CLR Table Value Function Example</title>
		<link>http://nlsimmons.com/?p=106</link>
		<comments>http://nlsimmons.com/?p=106#comments</comments>
		<pubDate>Mon, 18 Oct 2010 19:43:24 +0000</pubDate>
		<dc:creator><![CDATA[]]></dc:creator>
				<category><![CDATA[SQL CLR]]></category>

		<guid isPermaLink="false">http://nlsimmons.com/SQLScraps/?p=71</guid>
		<description><![CDATA[Overview In this post I would like to demonstrate how to create a simple yet non-trivial CLR table-valued function (TVF).&#8230;]]></description>
				<content:encoded><![CDATA[            <script type="text/javascript" src="http://nlsimmons.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushSql.js"></script>
            <script type="text/javascript" src="http://nlsimmons.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushCSharp.js"></script>
<h4>Overview</h4>
<p>In this post I would like to demonstrate how to create a simple yet non-trivial CLR table-valued function (TVF).  There are several examples of CLR TVFs on the net but the majority of them show only a trivial example.  It is very difficult, in some cases impossible, to apply the principles and code in those examples to your own CLR TVF.  The TVF outlined in this post is used to return the IP address for a given host name.  At my shop we needed a way to log the IP a user connects from when they perform certain actions in the database.  .NET can readily perform this work so why not create a TVF to return the IP addresses for a user?  Sometimes this function will get called on a machine with two or more IPs (wireless and physical LAN) so a scalar function will not work here. What makes this TVF non-trivial in my opinion is that it does not just output an already formatted table; you have to build the output. </p>
<p>Without further ado, let&#8217;s dive in.  The following code is full C# source code for the function.  I will first divulge the entire code and then explain the pieces.</p>
<p><pre class="brush: csharp">using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Net;                       // Bring in classes necessary for working with IPs
using System.Collections;               // Bring in the IEnumberable defintion
using System.Collections.Generic;       // Bring in the List&lt;T&gt; class

public class Class_mfn_dnslookup
{
    [SqlFunction(Name = &quot;mfn_dnslookup&quot;, FillRowMethodName = &quot;FillRow&quot;, TableDefinition = &quot;IP NVARCHAR(20)&quot;)]
    public static IEnumerable mfn_dnslookup(SqlString hostname)
    {
        string c_hostname = hostname.ToString();
        IPHostEntry host;
        host = Dns.GetHostEntry(c_hostname);

        List&lt;object[]&gt; resultItems = new List&lt;object[]&gt;();

        foreach (IPAddress ip in host.AddressList)
        {
            if (!IPAddress.IsLoopback(ip) &amp;&amp; ip.ToString().IndexOf(&quot;.&quot;) != -1)
            {
                object[] item = new object[1];
                item.SetValue(ip.ToString(), 0);

                resultItems.Add(item);
            }
        }
        return resultItems;
    }

    public static void FillRow(Object obj, out SqlString IP)
    {
        object[] item = (object[])obj;
        IP = (SqlString)item[0].ToString();
    }
};
</pre></p>
<h4>Code Guts</h4>
<p>In line 10 we define the FillRowMethodName which will dictate how the return table is built.  We also define the TableDefinition for the output table.  Note that Line 11 uses the output type IEnumerable.  This type interacts closely with the FillRow method specified earlier.  This also allows for the table to be returned as rows are filled, instead of waiting for all rows to be populated and then returned.  This is particularly handy when returning large data sets that you want to begin viewing right away.  To build a result set, I assign the IP address to an index within an object array of static length (lines 23 and 24).  This array only has the one slot, which is fine since each adapter has only one IP address.  I then add this array to the resultItems list (line 26).  Line 29 returns the resultItems list.  But to where? Or what?  This is where the IEnumerable class comes back into play.  For CLR TVFs, the data being returned (resultItems list in this case) is operated on by the FillRow method, row by row.</p>
<p>So, the resultItems list, when returned, is passed through the FillRow method.  Lines 34 and 35 show how values are set for one output row.  The IP output in these lines corresponds to the [IP] column in the table definition. This happens for each output row in the resultItems list that is passed into the FillRow method.  The results are sent back to the calling client as they are returned.</p>
<h4>Conclusion</h4>
<p>While there are several postings about CLR TVFs, I felt none of them explained their code well enough, namely the FillRow method.  Jonathan Kehayias has a decent post at <a href="http://www.sqlclr.net/Examples/tabid/55/articleType/ArticleView/articleId/20/Default.aspx">SQLCLR.net</a>.  I took the concepts from his post and applied them to my situation.  Hopefully my explanation will help you better understand how to create a meaningful CLR TVF.</p>
]]></content:encoded>
			<wfw:commentRss>http://nlsimmons.com/?feed=rss2&#038;p=106</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
