{"id":766,"date":"2007-09-19T18:25:00","date_gmt":"2007-09-19T18:25:00","guid":{"rendered":"\/blogs\/bobb\/post\/SQLCLR-and-system-functionality-in-SQL-Server-2008-part-3.aspx"},"modified":"2007-09-19T18:25:00","modified_gmt":"2007-09-19T18:25:00","slug":"sqlclr-and-system-functionality-in-sql-server-2008-part-3","status":"publish","type":"post","link":"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/","title":{"rendered":"SQLCLR and system functionality in SQL Server 2008 &#8211; part 3"},"content":{"rendered":"<p>\nSo, Microsoft.SqlServer.Types lives in the resource database and runs in its own appdomain when its used by system functions, like SELECT * FROM sys.assemblies. Let&#39;s try an experiment with the following setup.\n<\/p>\n<p>\nI have two user assemblies in a database named &quot;test&quot;. One doesn&#39;t access any .NET types, its called datetest. The new DATE\/TIME-related data type series are not .NET-based, but you can use them in SQLCLR procs, as you can use NVARCHAR data type. There are some restrictions on DATE\/TIME series, more about that later. My second user assembly is named hiertest. It uses the HierarchyID data type in SQLCLR code. That&#39;s (of course) OK too. Both my user assemblies are owned by DBO. Both catalog as SAFE_ACCESS.&nbsp; There are no user assemblies in pubs database. Turn on SQL Profiler.\n<\/p>\n<p>\nIn pubs: SELECT * FROM sys.assemblies;\n<\/p>\n<p>\nIn profiler:<br \/>\nAssembly Load event: <br \/>\nAssembly Load Failed for requested assembly system.enterpriseservices, version=2.0.0.0, culture=neutral, publickeytoken=b03f5f7f11d50a3a, processorarchitecture=x86 with Error code: 0x80070002<br \/>\nIn SQL Server Log:<br \/>\n&nbsp;Common language runtime (CLR) functionality initialized using&#8230;<br \/>\n&nbsp;AppDomain 2 (32767.sys[runtime].1) created<br \/>\n&nbsp;&nbsp;&nbsp; <br \/>\nStill in pubs: declare @h hierarchyid; select HierarchyID::GetRoot(); &#8212; invoke static method of hierarchyid data type\n<\/p>\n<p>\nIn profiler:<br \/>\n&nbsp;Assembly Load Succeeded for Microsoft.SqlTypes.Types<br \/>\nIn SQL Server Log:<br \/>\n&nbsp;Unsafe assembly &#39;microsoft.sqlserver.types&#8230;&quot; loaded into AppDomain 2 (32767.sys[runtime].1)\n<\/p>\n<p>\nUSE test<br \/>\nGO\n<\/p>\n<p>\nIn test: SELECT * FROM sys.assemblies;<br \/>\nIn SQL Server log:<br \/>\nAssembly Load Failed for requested assembly system.enterpriseservices, version=2.0.0.0, culture=neutral, publickeytoken=b03f5f7f11d50a3a, processorarchitecture=x86 with Error code: 0x80070002<br \/>\n&nbsp;&nbsp; <br \/>\nIn test: EXEC dbo.somedateproc &#8212; my SQLCLR proc that uses date.<br \/>\nIn SQL Server log:<br \/>\n&nbsp;AppDomain 3 (test.dbo[runtime].2) created <br \/>\nIn profiler:<br \/>\n&nbsp;Assembly Load Succeeded for datetimetest<br \/>\n&nbsp;&nbsp; <br \/>\nIn test: SELECT * FROM dbo.AncestorAndSelf(&#39;\/&#39;); &#8212; my SQLCLR UDF that uses HierarchyID<br \/>\nIn SQL Server log:<br \/>\n&nbsp;Unsafe assembly &#39;microsoft.sqlserver.types&#8230;&quot; loaded into AppDomain 3 (test.dbo[runtime].2)<br \/>\nIn profiler:<br \/>\n&nbsp;Assembly Load Succeeded for Microsoft.SqlTypes.Types<br \/>\n&nbsp;Assembly Load Succeeded for hiertest\n<\/p>\n<p>\nSo what happened??\n<\/p>\n<p>\nThere is only one resource database appdomain, it gets created when system functions (sys.assemblies) use system assemblies. The actual assembly that contains the system .NET data types loads only when it&#39;s required, into the resource database&#39;s appdomain. By the way, the declaration of a (NULL) hierarchyID variable isn&#39;t enough to load the assembly, you must actually use the variable. If you use only TSQL and the new data types, only this one appdomain is needed, regardless of how many different databases use them.\n<\/p>\n<p>\nAdditonal appdomains are created on a per-database, per-assembly owner basis as in SQL Server 2005. Each &quot;user&quot; appdomain will also load the system assembly Microsoft.SqlTypes.Types, if and only if it needs it. That is, if you use HierarchyID (or Geometry\/Geography) in a SQLCLR procedure.\n<\/p>\n<p>\nOne last bit. Why are the appdomains referred to as: &quot;AppDomain 2 (32767.sys[runtime].1)&quot; and what happened to AppDomain 1? When .NET is loading into any executing process, there is a single appdomain created, the default appdomain. AppDomain 1. SQL Server doesn&#39;t load Microsoft.SqlServer.Types into this default appdomain, but starts another for the resource database. That&#39;s AppDomain 2 (into the process). The &quot;.1&quot; in &quot;32767.sys[runtime].1&quot; is first user appdomain.\n<\/p>\n<p>\nDatabase administrators like to know about everything going on in &quot;their&quot; database, and with good reason&#8230;if the database fails (or even runs slowly) its (s)he who gets the first&nbsp;phone call for help. SQLCLR is still relatively new. Hope this was helpful in explaining what&#39;s going on. But remember, the exact appdomain implementation could be refined further in later releases. Cheers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So, Microsoft.SqlServer.Types lives in the resource database and runs in its own appdomain when its used by system functions, like SELECT * FROM sys.assemblies. Let&#39;s try an experiment with the following setup. I have two user assemblies in a database named &quot;test&quot;. One doesn&#39;t access any .NET types, its called datetest. The new DATE\/TIME-related data [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29,38],"tags":[],"class_list":["post-766","post","type-post","status-publish","format-standard","hentry","category-sql-server-2008","category-sqlclr"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.9.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>SQLCLR and system functionality in SQL Server 2008 - part 3 - Bob Beauchemin<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"SQLCLR and system functionality in SQL Server 2008 - part 3 - Bob Beauchemin\" \/>\n<meta property=\"og:description\" content=\"So, Microsoft.SqlServer.Types lives in the resource database and runs in its own appdomain when its used by system functions, like SELECT * FROM sys.assemblies. Let&#039;s try an experiment with the following setup. I have two user assemblies in a database named &quot;test&quot;. One doesn&#039;t access any .NET types, its called datetest. The new DATE\/TIME-related data [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/\" \/>\n<meta property=\"og:site_name\" content=\"Bob Beauchemin\" \/>\n<meta property=\"article:published_time\" content=\"2007-09-19T18:25:00+00:00\" \/>\n<meta name=\"author\" content=\"Bob Beauchemin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Bob Beauchemin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/\",\"url\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/\",\"name\":\"SQLCLR and system functionality in SQL Server 2008 - part 3 - Bob Beauchemin\",\"isPartOf\":{\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website\"},\"datePublished\":\"2007-09-19T18:25:00+00:00\",\"dateModified\":\"2007-09-19T18:25:00+00:00\",\"author\":{\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"SQL Server 2008\",\"item\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/category\/sql-server-2008\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"SQLCLR and system functionality in SQL Server 2008 &#8211; part 3\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website\",\"url\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/\",\"name\":\"Bob Beauchemin\",\"description\":\"SQL Server Blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e\",\"name\":\"Bob Beauchemin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g\",\"caption\":\"Bob Beauchemin\"},\"sameAs\":[\"http:\/www.sqlskills.com\/blogs\/bobb\/\"],\"url\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/author\/bobb\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"SQLCLR and system functionality in SQL Server 2008 - part 3 - Bob Beauchemin","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/","og_locale":"en_US","og_type":"article","og_title":"SQLCLR and system functionality in SQL Server 2008 - part 3 - Bob Beauchemin","og_description":"So, Microsoft.SqlServer.Types lives in the resource database and runs in its own appdomain when its used by system functions, like SELECT * FROM sys.assemblies. Let&#39;s try an experiment with the following setup. I have two user assemblies in a database named &quot;test&quot;. One doesn&#39;t access any .NET types, its called datetest. The new DATE\/TIME-related data [&hellip;]","og_url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/","og_site_name":"Bob Beauchemin","article_published_time":"2007-09-19T18:25:00+00:00","author":"Bob Beauchemin","twitter_misc":{"Written by":"Bob Beauchemin","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/","url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/","name":"SQLCLR and system functionality in SQL Server 2008 - part 3 - Bob Beauchemin","isPartOf":{"@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website"},"datePublished":"2007-09-19T18:25:00+00:00","dateModified":"2007-09-19T18:25:00+00:00","author":{"@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e"},"breadcrumb":{"@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/sqlclr-and-system-functionality-in-sql-server-2008-part-3\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.sqlskills.com\/blogs\/bobb\/"},{"@type":"ListItem","position":2,"name":"SQL Server 2008","item":"https:\/\/www.sqlskills.com\/blogs\/bobb\/category\/sql-server-2008\/"},{"@type":"ListItem","position":3,"name":"SQLCLR and system functionality in SQL Server 2008 &#8211; part 3"}]},{"@type":"WebSite","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website","url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/","name":"Bob Beauchemin","description":"SQL Server Blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.sqlskills.com\/blogs\/bobb\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e","name":"Bob Beauchemin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g","caption":"Bob Beauchemin"},"sameAs":["http:\/www.sqlskills.com\/blogs\/bobb\/"],"url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/author\/bobb\/"}]}},"_links":{"self":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/posts\/766","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/comments?post=766"}],"version-history":[{"count":0,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/posts\/766\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/media?parent=766"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/categories?post=766"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/tags?post=766"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}