<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">BLOG DE MAXI ACCOTTO</title><subtitle type="html">Blog de SQLServer </subtitle><id>http://msmvps.com/blogs/maxiaccotto/atom.aspx</id><link rel="alternate" type="text/html" href="http://msmvps.com/blogs/maxiaccotto/default.aspx" /><link rel="self" type="application/atom+xml" href="http://msmvps.com/blogs/maxiaccotto/atom.aspx" /><generator uri="http://communityserver.org" version="4.1.40407.4157">Community Server</generator><updated>2007-08-12T22:34:00Z</updated><entry><title>Mudanza</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2009/03/27/mudanza.aspx" /><id>/blogs/maxiaccotto/archive/2009/03/27/mudanza.aspx</id><published>2009-03-27T11:24:00Z</published><updated>2009-03-27T11:24:00Z</updated><content type="html">&lt;p&gt;Hola gente, a partir de marzo de 2009 mi nuevo blog es: blog.maxiaccotto.com , los espero ahi &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1682036" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author></entry><entry><title>Material del curso básico de SQL Server 2008</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2009/03/14/material-del-curso-b-225-sico-de-sql-server-2008.aspx" /><id>/blogs/maxiaccotto/archive/2009/03/14/material-del-curso-b-225-sico-de-sql-server-2008.aspx</id><published>2009-03-14T12:41:10Z</published><updated>2009-03-14T12:41:10Z</updated><content type="html">&lt;p&gt;En el mes de febrero he dictado un curso de 3 días en el &lt;a href="http://www.mug.org.ar/Eventos/3203.aspx" target="_blank"&gt;MUG&lt;/a&gt; (Club de usuarios Microsoft) de Argentina para aquellos que recién se inician sobre SQL Server. El curso fue dado todo sobre la edición &lt;a href="http://www.microsoft.com/express/sql/download/" target="_blank"&gt;Express&lt;/a&gt; (gratuita) y se han mostrado desde las cosas básicas hasta como migrar una base de datos Fox a SQL Server.&lt;/p&gt;  &lt;p&gt;Aquí les dejo el &lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/maxiaccotto/EJEMPLOS.zip" target="_blank"&gt;link&lt;/a&gt; del material de los ejemplos de dicho curso&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1678065" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author></entry><entry><title>Generando Script de estructuras y datos con el Management Studio</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2009/02/26/generando-script-de-estructuras-y-datos-con-el-management-studio.aspx" /><id>/blogs/maxiaccotto/archive/2009/02/26/generando-script-de-estructuras-y-datos-con-el-management-studio.aspx</id><published>2009-02-26T12:20:19Z</published><updated>2009-02-26T12:20:19Z</updated><content type="html">&lt;p&gt;&lt;a href="http://blog.maxiaccotto.com/post/2009/07/09/generando-script-de-estructuras-y-datos-con-el-management-studio.aspx" target="_blank"&gt;Link&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1674069" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author><category term="SQL 2008" scheme="http://msmvps.com/blogs/maxiaccotto/archive/tags/SQL+2008/default.aspx" /></entry><entry><title>Error al querer eliminar un job de SQL Server 2005</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2009/01/03/error-al-querer-eliminar-un-job-de-sql-server.aspx" /><id>/blogs/maxiaccotto/archive/2009/01/03/error-al-querer-eliminar-un-job-de-sql-server.aspx</id><published>2009-01-03T17:43:59Z</published><updated>2009-01-03T17:43:59Z</updated><content type="html">&lt;p&gt;Al intentar eliminar un Job del SQL Server 2005 puede aparecer el siguiente mensaje de error &lt;/p&gt; &lt;p&gt;&lt;font color="#808080"&gt;The DELETE statement conflicted with the REFERENCE constraint “FK_subplan_job_id”. The conflict occurred in database “msdb”, table “dbo.sysmaintplan_subplans”, column ‘job_id’.&lt;br /&gt;The statement has been terminated. (Microsoft SQL Server, Error: 547) &lt;/font&gt;&lt;/p&gt; &lt;p&gt;nos indica que no se puede eliminar un job por problemas con los planes de mantenimiento.&lt;/p&gt; &lt;p&gt;Para poder resolver este problema y poder eliminar el Job les dejo el siguiente Script &lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;declare&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt; @job_name &lt;span style="color:blue;"&gt;varchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;500&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;set&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt; @job_name &lt;span style="color:gray;"&gt;=&lt;/span&gt; &lt;span style="color:red;"&gt;N&amp;#39;tujob&amp;#39;&lt;/span&gt; &lt;span style="color:gray;"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:gray;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;USE&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt; [msdb]&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;delete&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt; sysmaintplan_log&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;FROM&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt; sysmaintplan_subplans &lt;span style="color:blue;"&gt;AS&lt;/span&gt; subplan &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:gray;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;INNER&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt; &lt;span style="color:gray;"&gt;JOIN&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;sysjobs_view&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; jobs &lt;span style="color:blue;"&gt;ON&lt;/span&gt; subplan&lt;span style="color:gray;"&gt;.&lt;/span&gt;job_id &lt;span style="color:gray;"&gt;=&lt;/span&gt; jobs&lt;span style="color:gray;"&gt;.&lt;/span&gt;job_id &lt;span style="color:gray;"&gt;INNER&lt;/span&gt; &lt;span style="color:gray;"&gt;JOIN&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;sysmaintplan_log &lt;span style="color:blue;"&gt;ON&lt;/span&gt; subplan&lt;span style="color:gray;"&gt;.&lt;/span&gt;subplan_id &lt;span style="color:gray;"&gt;=&lt;/span&gt; sysmaintplan_log&lt;span style="color:gray;"&gt;.&lt;/span&gt;subplan_id&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;WHERE &lt;/span&gt;&lt;span style="font-size:10pt;color:gray;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;(&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;jobs&lt;span style="color:gray;"&gt;.&lt;/span&gt;name &lt;span style="color:gray;"&gt;=&lt;/span&gt; @job_name&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:gray;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;delete&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt; sysmaintplan_subplans&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;FROM&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt; sysmaintplan_subplans &lt;span style="color:blue;"&gt;AS&lt;/span&gt; subplan &lt;span style="color:gray;"&gt;INNER&lt;/span&gt; &lt;span style="color:gray;"&gt;JOIN&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;sysjobs_view&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; jobs &lt;span style="color:blue;"&gt;ON&lt;/span&gt; subplan&lt;span style="color:gray;"&gt;.&lt;/span&gt;job_id &lt;span style="color:gray;"&gt;=&lt;/span&gt; jobs&lt;span style="color:gray;"&gt;.&lt;/span&gt;job_id&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;WHERE &lt;/span&gt;&lt;span style="font-size:10pt;color:gray;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;(&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;jobs&lt;span style="color:gray;"&gt;.&lt;/span&gt;name &lt;span style="color:gray;"&gt;=&lt;/span&gt; @job_name&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:gray;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;delete&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:normal;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt;from&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-ansi-language:en-us;mso-no-proof:yes;"&gt; msdb&lt;span style="color:gray;"&gt;.&lt;/span&gt;dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:green;"&gt;sysjobs_view&lt;/span&gt; &lt;span style="color:blue;"&gt;where&lt;/span&gt; name &lt;span style="color:gray;"&gt;=&lt;/span&gt; @job_name&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1658416" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author></entry><entry><title>Se libero el Service Pack 3 del SQL Server 2005</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2008/12/27/se-libero-el-service-pack-3-del-sql-server-2005.aspx" /><id>/blogs/maxiaccotto/archive/2008/12/27/se-libero-el-service-pack-3-del-sql-server-2005.aspx</id><published>2008-12-27T15:04:51Z</published><updated>2008-12-27T15:04:51Z</updated><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Luego de unos meses en CTP ya esta disponible para descargar el &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=ae7387c3-348c-4faa-8ae5-949fdfbe59c4&amp;amp;displaylang=en"&gt;SP3&lt;/a&gt; del SQL server 2005. Lo instale en un cliente y por ahora todo bien :)&lt;/p&gt; &lt;p&gt;Aparte de incluir los hotfix también hay algunos cambios funcionales , aquí les dejo el &lt;a href="http://msdn.microsoft.com/es-es/library/dd353312(SQL.90).aspx"&gt;enlace&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1657832" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author></entry><entry><title>Como evitar que se acceda a nuestro SQL vía Excel</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2008/11/04/como-evitar-que-se-acceda-a-nuestro-sql-v-237-a-excel.aspx" /><id>/blogs/maxiaccotto/archive/2008/11/04/como-evitar-que-se-acceda-a-nuestro-sql-v-237-a-excel.aspx</id><published>2008-11-04T23:18:20Z</published><updated>2008-11-04T23:18:20Z</updated><content type="html">&lt;p&gt;En nuestras empresas o en clientes hay muchas veces que tenemos la necesidad de restringir el acceso a nuestro SQL desde ciertas aplicaciones como podría ser el paquete Office. A partir de SQL Server 2005 y con la incorporación de los triggers DDL podemos hacer esto de forma bastante simple.&lt;/p&gt; &lt;p&gt;Aquí les dejo un ejemplo de trigger DDL a nivel servidor de base de datos que no permitirá login desde aplicaciones Office.&lt;/p&gt; &lt;p&gt;CREATE TRIGGER [connection_limit_trigger]&lt;br /&gt;ON ALL SERVER &lt;br /&gt;FOR LOGON&lt;br /&gt;AS  &lt;p&gt;set nocount on  &lt;p&gt;-- con este trigger controlamos quienes no pueden hacer login a SQL  &lt;p&gt;BEGIN&lt;br /&gt;IF app_name() like &amp;#39;%Office%&amp;#39;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ROLLBACK;&lt;br /&gt;END;&lt;br /&gt;GO  &lt;p&gt;SET ANSI_NULLS OFF&lt;br /&gt;GO  &lt;p&gt;SET QUOTED_IDENTIFIER OFF&lt;br /&gt;GO  &lt;p&gt;ENABLE TRIGGER [connection_limit_trigger] ON ALL SERVER&lt;br /&gt;GO &lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1653079" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author><category term="sql 2005" scheme="http://msmvps.com/blogs/maxiaccotto/archive/tags/sql+2005/default.aspx" /><category term="SQL 2008" scheme="http://msmvps.com/blogs/maxiaccotto/archive/tags/SQL+2008/default.aspx" /></entry><entry><title>Error inesperado en Sharepoint consumiendo reportes de Reporting Service</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2008/10/31/error-inesperado-en-sharepoint-consumiendo-reportes-de-reporting-service.aspx" /><id>/blogs/maxiaccotto/archive/2008/10/31/error-inesperado-en-sharepoint-consumiendo-reportes-de-reporting-service.aspx</id><published>2008-10-31T02:12:00Z</published><updated>2008-10-31T02:12:00Z</updated><content type="html">&lt;p&gt;Si tienen integrado a Sherepoint (ya sea el portal o bien el services) son Reporting services y ejecutan un reporte que dura mas de dos minutos les aparecerá del lado de Sharepoint el siguiente error: Error inesperado o bien “An unexpected error has occurred” en ingles.&lt;/p&gt; &lt;p&gt;Por defecto existe un timeout a nivel ASP que es de 2 minutos, para cambiar este valor habrá que hacer los siguientes pasos desde el servidor de Sharepoint&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Abrir el archivo web.config de la aplicación sharepoint (por ejemplo \inetpub\wwwroot\wss\VirtualDirectories\80)&lt;/li&gt; &lt;li&gt;Buscar dentro del archivo httpRuntime&lt;/li&gt; &lt;li&gt;Agregar executionTimeout con un valor en segundos deseado, por ejemplo 1800&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&amp;lt;httpRuntime maxRequestLength=&amp;quot;51200&amp;quot; executionTimeout = &amp;quot;1800&amp;quot; /&amp;gt;&lt;/p&gt; &lt;p&gt;Esto nos permitirá extender el timeout del sharepoint haciendo que si tenemos reportes con una duración mayor a dos minutos los podamos ejecutar sin errores. Les recomiendo poner 1800 segundos ya que también ese valor es el predeterminados a nivel Reporting Service para un timeout de Reporte.&lt;/p&gt; &lt;p&gt;Aquí les dejo el &lt;a href="http://msdn.microsoft.com/en-us/library/ms159704(SQL.90).aspx" target="_blank"&gt;link&lt;/a&gt; original de donde he sacado la solución y me ha funcionado perfecto.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1652599" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author></entry><entry><title>Service pack 3 de SQL Server 2005</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2008/10/29/service-pack-3-de-sql-server-2005.aspx" /><id>/blogs/maxiaccotto/archive/2008/10/29/service-pack-3-de-sql-server-2005.aspx</id><published>2008-10-29T16:37:22Z</published><updated>2008-10-29T16:37:22Z</updated><content type="html">&lt;p&gt;Ya se puede empezar a descargar y probar el beta del service pack3 de SQL Server 2005.&lt;/p&gt; &lt;p&gt;Aqui les dejo el &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=D22317E1-BC64-4936-A14B-7A632B50A4CA&amp;amp;displaylang=en" target="_blank"&gt;link&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1652379" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author></entry><entry><title>Migración de WSS a otra máquina y hasta cambiando el servidor de base de datos</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2008/10/22/migraci-243-n-de-wss-a-otra-m-225-quina-y-hasta-cambiando-el-servidor-de-base-de-datos.aspx" /><id>/blogs/maxiaccotto/archive/2008/10/22/migraci-243-n-de-wss-a-otra-m-225-quina-y-hasta-cambiando-el-servidor-de-base-de-datos.aspx</id><published>2008-10-22T15:50:39Z</published><updated>2008-10-22T15:50:39Z</updated><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Me encontré con este excelente &lt;a href="http://msmvps.com/blogs/cgross/archive/2007/05/09/moving-a-wss-3-0-site-to-a-new-farm.aspx" target="_blank"&gt;articulo&lt;/a&gt; el cual les recomiendo si necesitan pasar un sharepoint de un servidor a otro. Excelente :) &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1651628" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author></entry><entry><title>¿Donde esta el SAC (Surface Area Configuration) en SQL 2008?</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2008/10/18/191-donde-esta-el-sac-surface-area-configuration-en-sql-2008.aspx" /><id>/blogs/maxiaccotto/archive/2008/10/18/191-donde-esta-el-sac-surface-area-configuration-en-sql-2008.aspx</id><published>2008-10-18T17:22:44Z</published><updated>2008-10-18T17:22:44Z</updated><content type="html">&lt;p&gt;Al instalar muy contentos nuestro SQL Server 2008 nos vamos a encontrar con varias novedades muy buenas para los administradores y desarrolladores. Pero también nos vamos a encontrar con algunas cosas que antes teníamos y ahora no , como por ejemplo la herramienta&amp;nbsp; SAC (Surface Area Configuration) de 2005 la cual nos permitía entre otras cosas habilitar las conexiones entrantes, el CLR, DAC, etc.&lt;/p&gt; &lt;p&gt;Entonces como hacemos en 2008 si no disponemos de esta herramienta? Bueno siempre tenemos la posibilidad de usar sp_configure.&lt;/p&gt; &lt;p&gt;Pero si no queremos usar desde código TSQL y si hacerlo de forma gráfica entonces ahora debemos hacerlo así.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Entramos a nuestro Management Studio de 2008&lt;/li&gt; &lt;li&gt;Luego de entrar e iniciar sesión en un servidor, hacemos click alterno del mouse sobre el nombre del servidor y luego vamos a la opción del menú &amp;quot;Facet&amp;quot;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Al hacer esto entraremos a la siguiente pantalla&lt;/p&gt; &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/maxiaccotto.DondeestaelSACSurfaceAreaConfigurationen_5F00_CA2F/image_5F00_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="482" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/maxiaccotto.DondeestaelSACSurfaceAreaConfigurationen_5F00_CA2F/image_5F00_thumb.png" width="581" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Aquí simplemente debemos seleccionar en Facet la opción de &amp;quot;Surface Area Configuration&amp;quot; y ahora si podemos configurar las opciones de forma gráfica :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1651243" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author></entry><entry><title>Primera actualización de SQL Server 2008</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2008/10/18/primera-actualizaci-243-n-de-sql-server-2008.aspx" /><id>/blogs/maxiaccotto/archive/2008/10/18/primera-actualizaci-243-n-de-sql-server-2008.aspx</id><published>2008-10-18T16:51:48Z</published><updated>2008-10-18T16:51:48Z</updated><content type="html">&lt;p&gt;El 23 de Septiembre se libero el primer &lt;a href="http://support.microsoft.com/kb/956717/en-us" target="_blank"&gt;hotfix&lt;/a&gt; del producto. Yo lo he bajado y probado en una migración que estoy llevando adelante y no he tenido problemas. De hecho me ha solucionado algunos problemas que estaba teniendo con Reporting Service cuando hacia reportes bien grandes.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1651241" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author><category term="SQL 2008" scheme="http://msmvps.com/blogs/maxiaccotto/archive/tags/SQL+2008/default.aspx" /></entry><entry><title>Reporting Service es gratuito?</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2008/10/18/reporting-service-es-gratuito.aspx" /><id>/blogs/maxiaccotto/archive/2008/10/18/reporting-service-es-gratuito.aspx</id><published>2008-10-18T16:32:44Z</published><updated>2008-10-18T16:32:44Z</updated><content type="html">&lt;p&gt;Muchas veces se me hace esta pregunta o bien veo en foros la misma. La respuesta es SI. En la edición Express Advance Services es totalmente gratuita e incluye Reporting Service (ya sea 2005 o 2008).&lt;/p&gt; &lt;p&gt;Claro esta edición tiene algunas limitaciones pero lo que si es cierto que pueden desarrollar reportes tan complejos como en las ediciones Standard o Enterprise y luego si desean migrar a cualquier de estas ediciones no es necesario modificar nada de sus reportes.&lt;/p&gt; &lt;p&gt;La confusión por lo general viene ya que hay dos versiones de la edición Express de SQL (la común y la Advance Service) siendo solo esta ultima la que dispone de Reporting Service.&lt;/p&gt; &lt;p&gt;Aquí les dejo los links para poder descargar la Express &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=4c6ba9fd-319a-4887-bc75-3b02b5e48a40&amp;amp;DisplayLang=es" target="_blank"&gt;2005&lt;/a&gt; o &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=B5D1B8C3-FDA5-4508-B0D0-1311D670E336&amp;amp;displaylang=en" target="_blank"&gt;2008&lt;/a&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:d4707005-65c6-453f-a1df-e68c37fd926f" style="padding-right:0px;display:inline;padding-left:0px;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;Etiquetas de Technorati: &lt;a href="http://technorati.com/tags/Reporting%20Service" rel="tag"&gt;Reporting Service&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1651240" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author></entry><entry><title>Material sobre SQL Server 2008</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2008/10/18/material-sobre-sql-server-2008.aspx" /><id>/blogs/maxiaccotto/archive/2008/10/18/material-sobre-sql-server-2008.aspx</id><published>2008-10-18T16:20:04Z</published><updated>2008-10-18T16:20:04Z</updated><content type="html">&lt;p&gt;La gente de JumpStart ha publicado ya hace un tiempo bastante material sobre SQL 2008 (Vídeos, HOL, Script , PPT, etc). Imperdible este &lt;a href="http://sqlserver2008jumpstart.microsofttraining.com/content/info.asp?CcpSubsiteID=69&amp;amp;infoid=27" target="_blank"&gt;link&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1651236" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author></entry><entry><title>Reporting Service 2008 desde 0</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2008/10/12/reporting-service-2008-desde-0.aspx" /><id>/blogs/maxiaccotto/archive/2008/10/12/reporting-service-2008-desde-0.aspx</id><published>2008-10-12T13:24:00Z</published><updated>2008-10-12T13:24:00Z</updated><content type="html">&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:&amp;#39;Verdana&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;Los d&amp;iacute;as 10 y 11 de Octubre he estado en la hermosa ciudad de C&amp;oacute;rdoba haciendo una conferencia para el Club de usuarios Microsoft (MUG) sobre Reporting Service 2008.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:&amp;#39;Verdana&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;Primero quiero agradecer a los participantes de las jornadas ya que considerando que en argentina era un fin de semana largo han estado tanto el d&amp;iacute;a viernes como el s&amp;aacute;bado por la ma&amp;ntilde;ana.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:&amp;#39;Verdana&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;Aqu&amp;iacute; dejo el &lt;a target="_self" href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.UserFiles/00.00.00.24.15/RS2008_2D00_A_2D00_FONDO_2D00_EJEMPLOS.zip" title="Materialrs2008"&gt;link&lt;/a&gt; al material utilizado en dichas jornadas, espero lo disfruten.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1650624" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author></entry><entry><title>Como generar el numero de nuestros comprobantes sin morir en el intento</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2008/03/16/como-generar-el-numero-de-nuestros-comprobantes-sin-morir-en-el-intento.aspx" /><id>/blogs/maxiaccotto/archive/2008/03/16/como-generar-el-numero-de-nuestros-comprobantes-sin-morir-en-el-intento.aspx</id><published>2008-03-16T15:45:00Z</published><updated>2008-03-16T15:45:00Z</updated><content type="html">&lt;p&gt;En la mayoria de nuestras aplicaciones tenemos la necesidad de poder generar el numero de nuestros comprobantes (Ordenes de compra, pedidos de ventas, etc)&lt;/p&gt;
&lt;p&gt;Existen diferentes tecnicas para poder realizar esta operacion. En los ejemplos de este post mostrate las dos formas mas tradicionales de hacerlo y cuales son sus pros y contras de cada una.&lt;/p&gt;
&lt;p&gt;Para estos ejemplos crearemos una base de datos nueva con la siguiente sentencia&lt;/p&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;CREATE&lt;/font&gt; &lt;font color="#0000ff"&gt;DATABASE&lt;/font&gt; EJEMPLO_NUMERACION&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;Usando autonumericos&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Dentro de SQLserver podemos definir en un tipo de dato entero la posibilidad de que sea autoincremental, esto hara que de forma automatica el motor de base de datos calcule el valor que debe ir en ese campo. Usando esta posibilidad podriamos definir que en nuestros comprobantes el campo de numero sea autonumerico.&lt;/p&gt;
&lt;p&gt;El siguiente ejemplo ilustra como hacer esta operacion&lt;/p&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;USE&lt;/font&gt; EJEMPLO_NUMERACION&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;CREATE&lt;/font&gt; &lt;font color="#0000ff"&gt;TABLE&lt;/font&gt; OC &lt;font color="#808080"&gt;(&lt;/font&gt;ID &lt;font color="#0000ff"&gt;INT&lt;/font&gt; &lt;font color="#0000ff"&gt;IDENTITY&lt;/font&gt;&lt;font color="#808080"&gt;,&lt;/font&gt; FECHA &lt;font color="#0000ff"&gt;DATETIME&lt;/font&gt; &lt;font color="#808080"&gt;NOT&lt;/font&gt; &lt;font color="#808080"&gt;NULL,&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;CLIENTE &lt;font color="#0000ff"&gt;VARCHAR&lt;/font&gt;&lt;font color="#808080"&gt;(&lt;/font&gt;50&lt;font color="#808080"&gt;)&lt;/font&gt; &lt;font color="#808080"&gt;NOT&lt;/font&gt; &lt;font color="#808080"&gt;NULL)&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;Como se podra observer el campo ID es de tipo int y a su vez tiene la propiedad de ser autoincremental, el resto de los campos corresponden a datos necesarios de la Orden de compra de este ejemplo.&lt;/p&gt;
&lt;p&gt;Si queremos insertar un nuevo registro (o sea una nueva orden de compra) simplemente hacemos lo siguiente&lt;/p&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;INSERT&lt;/font&gt; &lt;font color="#0000ff"&gt;INTO&lt;/font&gt; OC &lt;font color="#808080"&gt;(&lt;/font&gt;FECHA&lt;font color="#808080"&gt;,&lt;/font&gt;CLIENTE&lt;font color="#808080"&gt;)&lt;/font&gt; &lt;/p&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;VALUES&lt;/font&gt; &lt;font color="#808080"&gt;(&lt;/font&gt;&lt;font color="#ff00ff"&gt;GETDATE&lt;/font&gt;&lt;font color="#808080"&gt;(),&lt;/font&gt;&lt;font color="#ff0000"&gt;&amp;#39;IBM&amp;#39;&lt;/font&gt;&lt;font color="#808080"&gt;)&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;go&lt;/p&gt;
&lt;p&gt;Si luego de esto hacemos un select a la tabla OC y vemos los registros podremos observar que se ha generado de forma automatica el ID 1, si hacemos otro insert valido veremos que se generara el 2 y asi sucesivamente.&lt;/p&gt;
&lt;p&gt;Ahora bien, que sucede si por ejemplo hacemos un insert y no se pudo realizar la transaccion, por ejemplo queremos insertar una OC donde el campo Cliente sea nulo lo cual no esta permitido por&amp;nbsp; la integridad de la base de datos.&lt;/p&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;INSERT&lt;/font&gt; &lt;font color="#0000ff"&gt;INTO&lt;/font&gt; OC &lt;font color="#808080"&gt;(&lt;/font&gt;FECHA&lt;font color="#808080"&gt;,&lt;/font&gt;CLIENTE&lt;font color="#808080"&gt;)&lt;/font&gt; &lt;/p&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;VALUES&lt;/font&gt; &lt;font color="#808080"&gt;(&lt;/font&gt;&lt;font color="#ff00ff"&gt;GETDATE&lt;/font&gt;&lt;font color="#808080"&gt;(),NULL)&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;go&lt;/p&gt;
&lt;p&gt;Al hacer esta instruccion recibiremos el siguiente error:&lt;/p&gt;&lt;font size="2"&gt;
&lt;p&gt;Msg 515, Level 16, State 2, Line 2&lt;/p&gt;
&lt;p&gt;Cannot insert the value NULL into column &amp;#39;CLIENTE&amp;#39;, table &amp;#39;EJEMPLO_NUMERACION.dbo.OC&amp;#39;; column does not allow nulls. INSERT fails.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Bien, el registro si hacemos un select a la tabla no se ha generado y eso es correcto ya que ha existido un problema.&lt;/p&gt;
&lt;p&gt;Ahora bien, hasta el momento solo tenemos generada la OC con ID = 1 y la 2 ha fallado. Pues arreglamos el tema del null en el insert para que se genere la OC = 2 ya que es la que continua luego de la 1.&lt;/p&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;INSERT&lt;/font&gt; &lt;font color="#0000ff"&gt;INTO&lt;/font&gt; OC &lt;font color="#808080"&gt;(&lt;/font&gt;FECHA&lt;font color="#808080"&gt;,&lt;/font&gt;CLIENTE&lt;font color="#808080"&gt;)&lt;/font&gt; &lt;/p&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;VALUES&lt;/font&gt; &lt;font color="#808080"&gt;(&lt;/font&gt;&lt;font color="#ff00ff"&gt;GETDATE&lt;/font&gt;&lt;font color="#808080"&gt;(),&lt;/font&gt;&lt;font color="#ff0000"&gt;&amp;#39;MICROSOFT&amp;#39;&lt;/font&gt;&lt;font color="#808080"&gt;)&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;go&lt;/p&gt;
&lt;p&gt;El registro se genero ahora &amp;quot;correctamente&amp;quot;, pero si hacemos un select a la tabla nos encontraremos que ahora tenemos el ID = 1 y el ID = 3, con lo cual estamos teniendo huecos en nuestra numeracion.&lt;/p&gt;
&lt;p&gt;Como se podra observar es un grave problema tener estos huecos en los numeros de los comprobantes (imagine que fueran facturas por ejemplo), pues esto se debe a como funciona el&amp;nbsp;autonumero de SQLServer, es simple de usar e implementar pero hay que saber&amp;nbsp;lo de las transacciones, ante una falla el numero&amp;nbsp;lo reservo igual y considero que se genero con lo cual lo salta&amp;nbsp;&lt;img src="http://msmvps.com/emoticons/emotion-6.gif" alt="Sad" /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;Usando tabla numeradora &lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Otra alternativa a la que vimos es la de generar una tabla donde tendremos los numeros de los comprobantes y usarla para numerar uno nuevo, si la transaccion fallo simplemente hay que tener el recaudo de no cambiar el valor en la tabla numeradora.&lt;/p&gt;
&lt;p&gt;Entonces, lo primero que generamos es esta tabla numeradora&lt;/p&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;CREATE&lt;/font&gt; &lt;font color="#0000ff"&gt;TABLE&lt;/font&gt; NUMERADOR &lt;font color="#808080"&gt;(&lt;/font&gt;TIPO_COMPROBANTE &lt;font color="#0000ff"&gt;VARCHAR&lt;/font&gt;&lt;font color="#808080"&gt;(&lt;/font&gt;100&lt;font color="#808080"&gt;),&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;ULTIMO_NUMERO &lt;font color="#0000ff"&gt;INT&lt;/font&gt;&lt;font color="#808080"&gt;)&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;GO&lt;/p&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;INSERT&lt;/font&gt; &lt;font color="#0000ff"&gt;INTO&lt;/font&gt; NUMERADOR &lt;font color="#0000ff"&gt;VALUES&lt;/font&gt; &lt;font color="#808080"&gt;(&lt;/font&gt;&lt;font color="#ff0000"&gt;&amp;#39;OC&amp;#39;&lt;/font&gt;&lt;font color="#808080"&gt;,&lt;/font&gt;1&lt;font color="#808080"&gt;)&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;INSERT&lt;/font&gt; &lt;font color="#0000ff"&gt;INTO&lt;/font&gt; NUMERADOR &lt;font color="#0000ff"&gt;VALUES&lt;/font&gt; &lt;font color="#808080"&gt;(&lt;/font&gt;&lt;font color="#ff0000"&gt;&amp;#39;FACTURAS&amp;#39;&lt;/font&gt;&lt;font color="#808080"&gt;,&lt;/font&gt;10&lt;font color="#808080"&gt;)&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;La tabla numeradora podra ser utilizada por distintos comprobantes, de ahi es que tiene un campo denominado tipo_comprobante y otro ultimo_numero.&lt;/p&gt;
&lt;p&gt;Como tambien se puede observar se le han insertado 2 registros, uno para los comprobantes de Ordendes de Compra y el otro para facturas.&lt;/p&gt;
&lt;p&gt;Ahora bien, lo que debemos hacer como siguiente paso es utilizar esta tabla numeradora para obtener el ultimo_numero sumarle 1 y asignarlo a la OC que estamos generando. Aqui entran a jugar una serie mas de detalles a conocer, si hacemos un Select (sin cambiar el nivel de bloqueo) y otro usuario en otro sitio hace lo mismo podran obtener el mismo ultimo_numero lo cual al sumarle 1 los dos intentaran hacer la misma OC. &lt;/p&gt;
&lt;p&gt;Para evitar este tipo de situaciones, ya que&amp;nbsp;no&amp;nbsp;solo necesito numerar sino tambien&amp;nbsp;asegurar que no exista la posibilidad&amp;nbsp;de obtener numeros duplicados (la misma OC por ejemplo) es que vamos a hacer uso de algunos trucos de bloqueos y variables.&lt;/p&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;DROP&lt;/font&gt; &lt;font color="#0000ff"&gt;TABLE&lt;/font&gt; OC&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;&lt;font color="#0000ff"&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;CREATE&lt;/font&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;font color="#0000ff"&gt;TABLE&lt;/font&gt;&lt;font color="#000000"&gt; OC &lt;/font&gt;&lt;font color="#808080"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;NUMERO &lt;/font&gt;&lt;font color="#0000ff"&gt;INT&lt;/font&gt;&lt;font color="#808080"&gt;,&lt;/font&gt;&lt;font color="#000000"&gt; FECHA &lt;/font&gt;&lt;font color="#0000ff"&gt;DATETIME&lt;/font&gt;&lt;font color="#808080"&gt;,&lt;/font&gt;&lt;font color="#000000"&gt;CLIENTE &lt;/font&gt;&lt;font color="#0000ff"&gt;VARCHAR&lt;/font&gt;&lt;font color="#808080"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;50&lt;/font&gt;&lt;font color="#808080"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;font color="#808080"&gt;NOT&lt;/font&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;font color="#808080"&gt;NULL)&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;&lt;/font&gt;GO&lt;/p&gt;&lt;font color="#0000ff"&gt;declare&lt;/font&gt; @proximo_numero &lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt; begin&lt;/font&gt; &lt;font color="#0000ff"&gt;try&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt; 
&lt;p&gt;begin&lt;/font&gt; &lt;font color="#0000ff"&gt;tran&lt;/p&gt;&lt;/font&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font color="#0000ff"&gt;update&lt;/font&gt; numerador &lt;font color="#0000ff"&gt;set&lt;/font&gt; @proximo_numero &lt;font color="#808080"&gt;=&lt;/font&gt; ultimo_numero &lt;font color="#808080"&gt;=&lt;/font&gt; ultimo_numero &lt;font color="#808080"&gt;+&lt;/font&gt; 1 &lt;/p&gt;
&lt;p&gt;&lt;font color="#0000ff"&gt;where&lt;/font&gt; tipo_comprobante &lt;font color="#808080"&gt;=&lt;/font&gt; &lt;font color="#ff0000"&gt;&amp;#39;OC&amp;#39;&lt;/font&gt;&lt;/p&gt;&lt;font color="#0000ff"&gt;INSERT&lt;/font&gt; &lt;font color="#0000ff"&gt;INTO&lt;/font&gt; OC &lt;font color="#0000ff"&gt;VALUES&lt;/font&gt; &lt;font color="#808080"&gt;(&lt;/font&gt;@proximo_numero&lt;font color="#808080"&gt;,&lt;/font&gt;&lt;font color="#ff00ff"&gt;getdate&lt;/font&gt;&lt;font color="#808080"&gt;(),&lt;/font&gt;&lt;font color="#ff0000"&gt;&amp;#39;SQLTOTAL&amp;#39;&lt;/font&gt;&lt;font color="#808080"&gt;)&lt;/font&gt;&lt;font color="#808080"&gt;&lt;/font&gt;&lt;font color="#808080"&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;commit&lt;/font&gt; &lt;font color="#0000ff"&gt;tran&lt;/font&gt;&lt;/p&gt;&lt;font color="#0000ff"&gt;end&lt;/font&gt; &lt;font color="#0000ff"&gt;try&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt; &lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;begin&lt;/font&gt; &lt;font color="#0000ff"&gt;catch&lt;/p&gt;&lt;/font&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font color="#0000ff"&gt;rollback&lt;/font&gt; &lt;font color="#0000ff"&gt;tran&lt;/font&gt; &lt;font color="#008000"&gt;-- primero hacemos un rollback&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;&lt;font color="#0000ff"&gt;print&lt;/font&gt; &lt;font color="#ff00ff"&gt;@@error&lt;/font&gt; &lt;font color="#008000"&gt;-- mostramos el error generado&lt;/p&gt;&lt;/blockquote&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;end&lt;/font&gt; &lt;font color="#0000ff"&gt;catch&lt;/font&gt; &lt;/p&gt;
&lt;p&gt;GO &lt;/p&gt;
&lt;p&gt;La sentencia UPDATE no solo modifica la tabla sino que ademas actualiza la variable que luego utilizamos para generar el comprobante. De esta manera logramos que si hay 2 procesos haciendo esto por el uso de los bloqueos internos de SQL al hacer uso de la instruccion UPDATE, el segundo proceso no podra hacer update hasta que el primero no haya terminado la transaccion (ya sea por commit o rollback tran)&lt;/p&gt;
&lt;p&gt;Si hacemos un select sobre OC vamos a observar que se ha generado el id numero 2, ahora bien si intentamos hacer un nuevo insert pero que falla y luego volvemos a insertar uno que no falla no tendremos los huecos en la numeracion como nos ha sucedido con los identity.&lt;/p&gt;
&lt;p&gt;Para probar que no se van a generar 2 numeros iguales en tiempos iguales hay que hacer la siguiente prueba con el Script.&lt;/p&gt;
&lt;p&gt;1) Habra&amp;nbsp;dos ventanas de management studio o Query Analizer si usa 2000&lt;/p&gt;
&lt;p&gt;2) En ambas copie por ejemplo este codigo&lt;/p&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;declare&lt;/font&gt; @proximo_numero &lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt; begin&lt;/font&gt; &lt;font color="#0000ff"&gt;try&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt; &lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;begin&lt;/font&gt; &lt;font color="#0000ff"&gt;tran&lt;/p&gt;&lt;/font&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font color="#0000ff"&gt;update&lt;/font&gt; numerador &lt;font color="#0000ff"&gt;set&lt;/font&gt; @proximo_numero &lt;font color="#808080"&gt;=&lt;/font&gt; ultimo_numero &lt;font color="#808080"&gt;=&lt;/font&gt; ultimo_numero &lt;font color="#808080"&gt;+&lt;/font&gt; 1 &lt;/p&gt;
&lt;p&gt;&lt;font color="#0000ff"&gt;where&lt;/font&gt; tipo_comprobante &lt;font color="#808080"&gt;=&lt;/font&gt; &lt;font color="#ff0000"&gt;&amp;#39;OC&amp;#39;&lt;/font&gt;&lt;/p&gt;&lt;font color="#0000ff"&gt;INSERT&lt;/font&gt; &lt;font color="#0000ff"&gt;INTO&lt;/font&gt; OC &lt;font color="#0000ff"&gt;VALUES&lt;/font&gt; &lt;font color="#808080"&gt;(&lt;/font&gt;@proximo_numero&lt;font color="#808080"&gt;,&lt;/font&gt;&lt;font color="#ff00ff"&gt;getdate&lt;/font&gt;&lt;font color="#808080"&gt;(),&lt;/font&gt;&lt;font color="#ff0000"&gt;&amp;#39;SQLTOTAL&amp;#39;&lt;/font&gt;&lt;font color="#808080"&gt;)&lt;/font&gt;&lt;font color="#808080"&gt;&lt;/font&gt;&lt;font color="#808080"&gt;&lt;/blockquote&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;end&lt;/font&gt; &lt;font color="#0000ff"&gt;try&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt; &lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;begin&lt;/font&gt; &lt;font color="#0000ff"&gt;catch&lt;/p&gt;&lt;/font&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font color="#0000ff"&gt;rollback&lt;/font&gt; &lt;font color="#0000ff"&gt;tran&lt;/font&gt; &lt;font color="#008000"&gt;-- primero hacemos un rollback&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;&lt;font color="#0000ff"&gt;print&lt;/font&gt; &lt;font color="#ff00ff"&gt;@@error&lt;/font&gt; &lt;font color="#008000"&gt;-- mostramos el error generado&lt;/p&gt;&lt;/blockquote&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;end&lt;/font&gt; &lt;font color="#0000ff"&gt;catch&lt;/font&gt; &lt;/p&gt;
&lt;p&gt;3) Ejecute desde la primer ventana el script, luego hagalo desde la segunda. Como podra observar en la segunda ventana se queda esperando y no procesa , esto se debe que hay bloqueos sobre la tabla numeradora y que el segundo update no ha podido ser realizado.&lt;/p&gt;
&lt;p&gt;4) En la primer ventana escriba commit tran y ejecute solo eso&lt;/p&gt;
&lt;p&gt;Al hacer esto podra observar que la segunda ventana ha terminado.&lt;/p&gt;
&lt;p&gt;5) Haga un select sobre OC y vea los resultados &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Bueno con esto termino, espero que les haya sido de utilidad y espero sus comentarios&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/font&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1544452" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author><category term="Best Practice" scheme="http://msmvps.com/blogs/maxiaccotto/archive/tags/Best+Practice/default.aspx" /></entry><entry><title>Se libero el CTP Febrero de SQL server 2008</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2008/02/22/se-libero-el-ctp-febrero-de-sql-server-2008.aspx" /><id>/blogs/maxiaccotto/archive/2008/02/22/se-libero-el-ctp-febrero-de-sql-server-2008.aspx</id><published>2008-02-22T13:53:00Z</published><updated>2008-02-22T13:53:00Z</updated><content type="html">&lt;p&gt;Ya esta disponible el nuevo&amp;nbsp;CTP de SQL2008&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=749BD760-F404-4D45-9AC0-D7F1B3ED1053&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyId=749BD760-F404-4D45-9AC0-D7F1B3ED1053&amp;amp;displaylang=en&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1521696" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author><category term="SQL 2008" scheme="http://msmvps.com/blogs/maxiaccotto/archive/tags/SQL+2008/default.aspx" /></entry><entry><title>Virtual Earth y SQL Server 2008</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2007/11/27/virtual-earth-y-sql-server-2008.aspx" /><id>/blogs/maxiaccotto/archive/2007/11/27/virtual-earth-y-sql-server-2008.aspx</id><published>2007-11-27T13:02:00Z</published><updated>2007-11-27T13:02:00Z</updated><content type="html">&lt;p&gt;SQL Server 2008 incorpora nuevos tipos de datos, uno de ellos es el tipo de datos Spatial.&lt;/p&gt;
&lt;p&gt;En este link les dejo un interesante articulo con todo su codigo de ejemplo donde se integra SQL 2008 al famoso Virtual Earth.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.viawindowslive.com/Articles/VirtualEarth/SQL2008Spatialafirstimpression.aspx"&gt;http://www.viawindowslive.com:80/Articles/VirtualEarth/SQL2008Spatialafirstimpression.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1361514" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author><category term="SQL 2008" scheme="http://msmvps.com/blogs/maxiaccotto/archive/tags/SQL+2008/default.aspx" /></entry><entry><title>Sql Dinamico y seguridad en SQL2005</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2007/11/08/sql-dinamico-y-seguridad-en-sql2005.aspx" /><id>/blogs/maxiaccotto/archive/2007/11/08/sql-dinamico-y-seguridad-en-sql2005.aspx</id><published>2007-11-08T23:56:00Z</published><updated>2007-11-08T23:56:00Z</updated><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;SQL-Dinámico y seguridad dentro de SQLServer 2005&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;El SQL-dinámico es una técnica la cual nos permite ejecutar sentencias TSQL de forma dinámica,&amp;nbsp; para poder hacer uso de esta técnica es necesario utilizar o bien el store procedure sp_executesql o sino EXEC(@str).&lt;/p&gt;
&lt;p&gt;Este articulo no tiene como objetivo entrar en detalle del SQL-dinámico ya que hay otros escritos al respecto como por ejemplo el siguiente link el cual recomiendo leer &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.hayes.ch/sql/sql_dinamico.html"&gt;http://www.hayes.ch/sql/sql_dinamico.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Aquí nos concentraremos en la seguridad y los cambios que hay en SQL2005 al respecto.&lt;/p&gt;
&lt;p&gt;Una de las mayores contras que tiene el uso de SQL-Dinámico es que si lo ponemos dentro de un Store Procedure el usuario que ejecute tal Store no solo deberá tener permisos de execute sino que también deberá tener permisos sobre los objetos que haga referencia el SQL-Dinámico.&lt;/p&gt;
&lt;p&gt;Para poder ser más específicos veamos un ejemplo al respecto&lt;/p&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;USE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;MASTER&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;GO&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;CREATE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;DATABASE&lt;/font&gt;&lt;font size="2"&gt; TEST1&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt; 
&lt;p&gt;GO&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;USE&lt;/font&gt;&lt;font size="2"&gt; TEST1&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt; 
&lt;p&gt;GO&lt;/p&gt;&lt;/font&gt;&lt;font color="#008000" size="2"&gt;
&lt;p&gt;-- CREAMOS UN NUEVO LOGIN&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;CREATE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;LOGIN&lt;/font&gt;&lt;font size="2"&gt; FEDERICO &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;WITH&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;PASSWORD&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#808080" size="2"&gt;=&lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;&amp;#39;PASSW@RD&amp;#39;&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;GO&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;USE&lt;/font&gt;&lt;font size="2"&gt; TEST1&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt; 
&lt;p&gt;GO&lt;/p&gt;&lt;/font&gt;&lt;font color="#008000" size="2"&gt;
&lt;p&gt;-- CREAMOS EL USUARIO EN LA BASE DE DATOS&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;CREATE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;USER&lt;/font&gt;&lt;font size="2"&gt; FEDERICO&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt; 
&lt;p&gt;GO&lt;/p&gt;&lt;/font&gt;&lt;font color="#008000" size="2"&gt;
&lt;p&gt;-- CREAMOS UNA TABLA&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;CREATE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;TABLE&lt;/font&gt;&lt;font size="2"&gt; DBO&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;EMPLEADOS &lt;/font&gt;&lt;font color="#808080" size="2"&gt;(&lt;/font&gt;&lt;font size="2"&gt;ID &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;INT&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;IDENTITY&lt;/font&gt;&lt;font color="#808080" size="2"&gt;,&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;NAME&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;VARCHAR&lt;/font&gt;&lt;font color="#808080" size="2"&gt;(&lt;/font&gt;&lt;font size="2"&gt;50&lt;/font&gt;&lt;font color="#808080" size="2"&gt;))&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;GO&lt;/p&gt;&lt;/font&gt;&lt;font color="#008000" size="2"&gt;
&lt;p&gt;-- CREAMOS UN STORE QUE CONSUME LA TABLA EMPLEADOS&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;CREATE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;PROC&lt;/font&gt;&lt;font size="2"&gt; DBO&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;USP_EMPLEADOS_GET_ALL &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;AS&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;SELECT&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#808080" size="2"&gt;*&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;FROM&lt;/font&gt;&lt;font size="2"&gt; DBO&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;EMPLEADOS&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt; 
&lt;p&gt;GO&lt;/p&gt;&lt;/font&gt;&lt;font color="#008000" size="2"&gt;
&lt;p&gt;-- CREAMOS OTRO STORE QUE CONSUME LA TABLA PERO CON SQLDINAMICO&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;CREATE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;PROC&lt;/font&gt;&lt;font size="2"&gt; DBO&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;USP_EMPLEADOS_GET_ALL2 &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;AS&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;DECLARE&lt;/font&gt;&lt;font size="2"&gt; @N &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;NVARCHAR&lt;/font&gt;&lt;font color="#808080" size="2"&gt;(&lt;/font&gt;&lt;font size="2"&gt;50&lt;/font&gt;&lt;font color="#808080" size="2"&gt;)&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;SET&lt;/font&gt;&lt;font size="2"&gt; @N &lt;/font&gt;&lt;font color="#808080" size="2"&gt;=&lt;/font&gt;&lt;font size="2"&gt; N&lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;&amp;#39;SELECT * FROM DBO.EMPLEADOS&amp;#39;&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;EXECUTE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#800000" size="2"&gt;SP_EXECUTESQL&lt;/font&gt;&lt;font size="2"&gt; @N&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt; 
&lt;p&gt;GO&lt;/p&gt;&lt;/font&gt;&lt;font color="#008000" size="2"&gt;
&lt;p&gt;-- FEDERICO SOLO TIENE PERMISOS A LOS STORES&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;GRANT&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;EXECUTE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;ON&lt;/font&gt;&lt;font size="2"&gt; DBO&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;USP_EMPLEADOS_GET_ALL &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;TO&lt;/font&gt;&lt;font size="2"&gt; FEDERICO&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;GRANT&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;EXECUTE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;ON&lt;/font&gt;&lt;font size="2"&gt; DBO&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;USP_EMPLEADOS_GET_ALL2 &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;TO&lt;/font&gt;&lt;font size="2"&gt; FEDERICO&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt; 
&lt;p&gt;GO&lt;/p&gt;&lt;/font&gt;&lt;font color="#008000" size="2"&gt;
&lt;p&gt;-- ENTRAMOS COMO FEDERICO&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;EXECUTE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;AS&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;LOGIN&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#808080" size="2"&gt;=&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;&amp;#39;FEDERICO&amp;#39;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;SELECT&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff00ff" size="2"&gt;SUSER_SNAME&lt;/font&gt;&lt;font color="#808080" size="2"&gt;()&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;SELECT&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#808080" size="2"&gt;*&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;FROM&lt;/font&gt;&lt;font size="2"&gt; DBO&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;EMPLEADOS &lt;/font&gt;&lt;font color="#008000" size="2"&gt;-- FALLA PORQUE NO TENEMOS PERMISO&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;EXEC&lt;/font&gt;&lt;font size="2"&gt; DBO&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;USP_EMPLEADOS_GET_ALL &lt;/font&gt;&lt;font color="#008000" size="2"&gt;-- FUNCIONA&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;EXEC&lt;/font&gt;&lt;font size="2"&gt; DBO&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;USP_EMPLEADOS_GET_ALL2 &lt;/font&gt;&lt;font color="#008000" size="2"&gt;-- FALLA POR EL SQL-DINAMICO&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;REVERT&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008000" size="2"&gt;-- REVERTIMOS EL LOGIN&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;Como se ha podido observar en el ejemplo el segundo Store ha fallado cuando el usuario Federico lo invoco ya que no tenia permisos sobre los objetos internos del mismo, en este caso la tabla &amp;quot;Empleados&amp;quot;.&lt;/p&gt;
&lt;p&gt;Esto atenta contra el buen uso de un Store procedure ya que una de sus virtudes es aislar a los usuarios del acceso directo a los objetos, con lo cual si deseamos en este caso usar SQL-Dinámico deberíamos darle permisos de Select a la tabla correspondiente.&lt;/p&gt;
&lt;p&gt;Esto funciona así en 2000 y no hay solución al respecto, por lo cual yo no recomiendo mucho el uso de SQL-Dinámico y de usarlo tener en claro lo que está sucediendo.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;¿Que cambios hay en 2005?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;SqlServer 2005 permite dentro de un objeto como el Store Procedure indicarle el contexto de ejecución, esto es totalmente nuevo y se indica con la sentencia WITH EXECUTE AS (Caller, Owner o Username)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Caller es utilizado por defecto y representa a quien llama (como vimos en el ejemplo 1)&lt;/li&gt;
&lt;li&gt;Owner indica que se impersonificara como el usuario propietario del objeto, en este caso como entre con la cuenta de SA entonces estamos impersonificando con ella.&lt;/li&gt;
&lt;li&gt;User_name nos permite indicar con que login deseamos que se impersonifique&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;El siguiente ejemplo modifica el &amp;nbsp;Store con SQL Dinámico pero utilizando Execute AS&lt;/p&gt;&lt;font color="#008000" size="2"&gt;
&lt;p&gt;-- CAMBIOS EL STORE DEL SQL DINAMO PARA QUE SE EJECUTE EN&lt;/p&gt;
&lt;p&gt;-- OTRO CONTEXTO DE SEGURIDAD&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;ALTER&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;PROC&lt;/font&gt;&lt;font size="2"&gt; DBO&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;USP_EMPLEADOS_GET_ALL2 &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;WITH&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;EXECUTE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;AS&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;OWNER&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;AS&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;DECLARE&lt;/font&gt;&lt;font size="2"&gt; @N &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;NVARCHAR&lt;/font&gt;&lt;font color="#808080" size="2"&gt;(&lt;/font&gt;&lt;font size="2"&gt;50&lt;/font&gt;&lt;font color="#808080" size="2"&gt;)&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;SET&lt;/font&gt;&lt;font size="2"&gt; @N &lt;/font&gt;&lt;font color="#808080" size="2"&gt;=&lt;/font&gt;&lt;font size="2"&gt; N&lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;&amp;#39;SELECT * FROM DBO.EMPLEADOS&amp;#39;&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;EXECUTE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#800000" size="2"&gt;SP_EXECUTESQL&lt;/font&gt;&lt;font size="2"&gt; @N&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt; 
&lt;p&gt;GO&lt;/p&gt;&lt;/font&gt;&lt;font color="#008000" size="2"&gt;
&lt;p&gt;-- VOLVEMOS A PROBAR&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;EXECUTE&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;AS&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;LOGIN&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#808080" size="2"&gt;=&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;&amp;#39;FEDERICO&amp;#39;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;SELECT&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff00ff" size="2"&gt;SUSER_SNAME&lt;/font&gt;&lt;font color="#808080" size="2"&gt;()&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;SELECT&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#808080" size="2"&gt;*&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;FROM&lt;/font&gt;&lt;font size="2"&gt; DBO&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;EMPLEADOS &lt;/font&gt;&lt;font color="#008000" size="2"&gt;-- FALLA PORQUE NO TENEMOS PERMISO&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;EXEC&lt;/font&gt;&lt;font size="2"&gt; DBO&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;USP_EMPLEADOS_GET_ALL &lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;EXEC&lt;/font&gt;&lt;font size="2"&gt; DBO&lt;/font&gt;&lt;font color="#808080" size="2"&gt;.&lt;/font&gt;&lt;font size="2"&gt;USP_EMPLEADOS_GET_ALL2 &lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;REVERT&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;Aquí se ve claramente que ahora Federico no necesito permisos sobre la tabla &amp;quot;Empleados&amp;quot; para poder hacer uso del SQL-Dinámico.&lt;/p&gt;
&lt;p&gt;Con esto lo que logramos es seguir manteniendo una de las enormes virtudes que tienen los Stores Procedures que es el aislamiento con respecto a los objetos base.&lt;/p&gt;
&lt;p&gt;No confundir el Execute AS del Store con el luego utilizado en el query para dentro del management Studio impersonificarnos como Federico sin la necesidad entrar a otra ventana.&lt;/p&gt;
&lt;p&gt;Estos ejemplos deben ser probados desde SQL2005, si desea probar el primer ejemplo desde SQL2000 deberá sacar la sentencia Execute AS y probar la seguridad entrando con el correspondiente login y password.&lt;/p&gt;
&lt;p&gt;Bueno espero les sea de utilidad y espero sus comentarios.&lt;/p&gt;
&lt;p&gt;Nos vemos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1288580" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author><category term="Seguridad" scheme="http://msmvps.com/blogs/maxiaccotto/archive/tags/Seguridad/default.aspx" /></entry><entry><title>Material de la charla en el MUG sobre programacion en SQLServer2005</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2007/08/23/material-de-la-charla-en-el-mug-sobre-programacion-en-sqlserver2005.aspx" /><id>/blogs/maxiaccotto/archive/2007/08/23/material-de-la-charla-en-el-mug-sobre-programacion-en-sqlserver2005.aspx</id><published>2007-08-23T15:54:00Z</published><updated>2007-08-23T15:54:00Z</updated><content type="html">&lt;p&gt;Este es el material que se ha utilizado en la jornada del MUG sobre programacion en SQLServer 2005&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/files/folders/maxiaccotto/entry1133223.aspx"&gt;http://msmvps.com/files/folders/maxiaccotto/entry1133223.aspx&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1133241" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author><category term="Material de eventos" scheme="http://msmvps.com/blogs/maxiaccotto/archive/tags/Material+de+eventos/default.aspx" /></entry><entry><title>Como crear el tipo de datos Hora en SQLServer 2005</title><link rel="alternate" type="text/html" href="/blogs/maxiaccotto/archive/2007/08/12/como-crear-el-tipo-de-datos-hora-en-sqlserver-2005.aspx" /><id>/blogs/maxiaccotto/archive/2007/08/12/como-crear-el-tipo-de-datos-hora-en-sqlserver-2005.aspx</id><published>2007-08-13T00:34:00Z</published><updated>2007-08-13T00:34:00Z</updated><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="center"&gt;&lt;b&gt;&lt;u&gt;Creando el tipo de datos hora en SQL2005 usando CLR&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;b&gt;&lt;u&gt;&lt;/u&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Introducción&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;SQLServer dispone de dos tipos de datos que son útiles para el almacenamiento de fechas y horas (Datetime &amp;amp; SmallDatetime). En muchas ocasiones necesitamos tener un tipo de datos exclusivo para almacenar únicamente las horas como así también poder hacer su tratamiento como podrían ser sumas, restas, promedios, etc.&lt;/p&gt;
&lt;p&gt;En este articulo veremos paso a paso como crear nuestro propio tipo de datos hora y poderlo utilizar como si fuere cualquier otro tipo de dato del motor nativo.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;CLR en SQL2005&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Una de las mayores incorporaciones que se le ha hecho a SQLServer 2005 es la posibilidad de crear objetos SQL (Triggers - Stores Procedures - User Function - User defined Type - Aggregate Function) utilizando .NET. La siguiente tabla muestra los tipos de objetos que se pueden crear con T-SQL y/o CLR.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table class="" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;&lt;b&gt;Tipo de Objeto&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;&lt;b&gt;TSQL&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;&lt;b&gt;CLR&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;Store Procedures&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;X&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;X&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;Triggers&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;X&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;X&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;User Function&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;X&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;X&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;User Defined Type&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;X&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;Aggregate Function&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;X&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Como se podrá observar si se desean crear &amp;quot;User defined Type&amp;quot; o bien &amp;quot;Aggregate Function&amp;quot; (como por ej. Sum, Avg, count,etc) es necesario hacerlos con CLR exclusivamente.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;En este articulo no entraremos en detalle de cómo funciona el CLR dentro de SQL2005 sino que nos concentraremos en como crear un&amp;nbsp; &amp;quot;User Defined Types&amp;quot;&amp;nbsp; (UDT)&lt;/p&gt;
&lt;p&gt;Debemos aclarar que no es necesario utilizar Visual Studio para poder programar en CLR dentro de SQL2005&amp;nbsp; pero si altamente recomendado por todas las facilidades que esta herramienta nos ofrece (Deploy - Debug , etc).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Al instalar SQL2005 por default no se activa el uso del CLR, esto es debido a que SQL2005 tiene como concepto &amp;quot;Seguro por defecto&amp;quot; con lo cual cierra todo tipo de funciones que pueden ser de alto riesgo.&lt;/p&gt;
&lt;p&gt;Para poder habilitar el uso del CLR se puede o bien utilizar el SAC (Sourface Area Configuration) o sino la siguiente sentencia TSQL.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;EXEC sp_configure &amp;#39;show advanced options&amp;#39;, 1&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;RECONFIGURE&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;sp_configure &amp;#39;clr enabled&amp;#39;, 1&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;RECONFIGURE&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Fig 1 Sourface Area Configuration&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Descripción de los User Defined Types&lt;/h1&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;En versiones anteriores a SQL2005 los UDT eran solamente Alias de otro tipo de dato como se muestra en el siguiente código.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;EXEC sp_addtype N&amp;#39;age&amp;#39;, N&amp;#39;tinyint&amp;#39;, N&amp;#39;not null&amp;#39;&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;CREATE RULE age_range&lt;/p&gt;
&lt;p&gt;AS&lt;/p&gt;
&lt;p&gt;@age &amp;gt;= 0 AND @age &amp;lt;=140&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;EXEC sp_bindrule N&amp;#39;age_range&amp;#39;, N&amp;#39;age&amp;#39;&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ahora en SQL2005 los UDT son muchos mas ricos donde todo el comportamiento esta embebido en el código de este.&lt;/p&gt;
&lt;p&gt;Los UDT deben respetar los siguientes requerimientos&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Soportar el concepto de Null (INullable)&lt;/li&gt;
&lt;li&gt;Soportar la conversión hacia y desde String&lt;/li&gt;
&lt;li&gt;Soportar la serialización&lt;/li&gt;
&lt;li&gt;Soportar un constructor por default&lt;/li&gt;
&lt;li&gt;Respetar las reglas de nombres (128 caracteres máximo)&lt;/li&gt;&lt;/ul&gt;
&lt;h1&gt;Creando el UDT desde Visual Studio 2005&lt;/h1&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Una de las maneras de poder crear este tipo de objeto es mediante Visual Studio 2005, para ello debemos generar un nuevo proyecto del tipo &amp;quot;Database&amp;quot; ya sea en C# o VB.NET.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Al realizar esta operación nuestro segundo paso en el asistente es indicar a que servidor de SQL2005 nos vamos a conectar&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Si nuestro servidor no se encuentra en la lista, debemos agregarlo desde el botón &amp;quot;Add New Reference..&amp;quot;&lt;/p&gt;
&lt;p&gt;Nuestro siguiente paso es agregar un componente a nuestra solución desde el &amp;quot;Solution Explorer&amp;quot;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Como podemos observar se pueden agregar Stores Procedures, User Defined Function, User Defined type, Trigger, Aggregate y Class. En nuestro caso usaremos &amp;quot;User Defined Type&amp;quot;. Cabe mencionar que dentro de una solución usted podría tener mas un ítem del tipo que fuere.&lt;/p&gt;
&lt;p&gt;Al realizar esta operación el Visual Studio nos genera la estructura necesaria para este objeto, en la siguiente figura se muestra un fragmento del código.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;using System;&lt;/p&gt;
&lt;p&gt;using System.Data;&lt;/p&gt;
&lt;p&gt;using System.Data.SqlClient;&lt;/p&gt;
&lt;p&gt;using System.Data.SqlTypes;&lt;/p&gt;
&lt;p&gt;using Microsoft.SqlServer.Server;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;[Serializable]&lt;/p&gt;
&lt;p&gt;[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native)]&lt;/p&gt;
&lt;p&gt;public struct udttime : INullable&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override string ToString()&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Replace the following code with your code&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &amp;quot;&amp;quot;;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;............&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ahora empezaremos modificando el código base para poder llegar a nuestro objetivo final.&lt;/p&gt;
&lt;p&gt;En principio le indicaremos una nueva propiedad &amp;quot;IsByteOrdered&amp;quot; a valor True para que el servidor utilice comparaciones ordenadas por Bytes.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;[Serializable]&lt;/p&gt;
&lt;p&gt;[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native,IsByteOrdered = true)]&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Nuestro siguiente paso es crear el código de estructura para nuestro tipo de datos UDTTIME.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;public struct UDTTIME : INullable&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private int milliseconds;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private bool m_Null;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static UDTTIME Parse(SqlString s)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (s.IsNull)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Null;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UDTTIME&amp;nbsp; x = new&amp;nbsp; UDTTIME();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TimeSpan ts = TimeSpan.Parse((string)s);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x.milliseconds = (int)ts.TotalMilliseconds;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return x;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override string ToString()............&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Aquí estamos usando el tipo de datos TimeSpan y trabajando los tiempos en milisegundos&lt;/p&gt;
&lt;p&gt;Ahora lo que haremos es implementar el método ToString con el siguiente código:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;public override string ToString()&lt;/p&gt;
&lt;p&gt;&amp;nbsp;{&lt;/p&gt;
&lt;p&gt;&amp;nbsp; return&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp; TimeSpan.FromMilliseconds(this.milliseconds).ToString();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Este método es de suma importancia ya que nos convertirá el valor del tipo timeSpan a algo legible por nuestros usuarios J&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Una de las cosas que se pueden hacer también dentro de un tipo de datos es definir funciones, imaginemos que ahora queremos tener dentro de este tipo de datos una función que nos permita a un valor Time X sumarle tantos milisegundos. Para poder realizar esto agregaremos el siguiente código&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;public UDTTIME Addtime(UDTTIME o)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (o.IsNull)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Null;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.milliseconds += o.milliseconds;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ahora debemos implementar el tratado de los tipos Null para ello implementaremos lo siguiente.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;public bool IsNull&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;{&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Put your code here&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return m_Null;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static UDTTIME Null&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UDTTIME h = new UDTTIME();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; h.m_Null = true;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return h;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ahora ya estamos en condiciones de poder hacer el deploy de este componente. El código completo ha quedado de la siguiente manera:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;using System.Data.SqlClient;&lt;/p&gt;
&lt;p&gt;using System.Data.SqlTypes;&lt;/p&gt;
&lt;p&gt;using Microsoft.SqlServer.Server;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;[Serializable]&lt;/p&gt;
&lt;p&gt;[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native,IsByteOrdered = true)]&lt;/p&gt;
&lt;p&gt;public struct UDTTIME : INullable&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp; milliseconds&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private int milliseconds;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Private member&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private bool m_Null;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static UDTTIME Parse(SqlString s)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (s.IsNull)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Null;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UDTTIME&amp;nbsp; x = new&amp;nbsp; UDTTIME();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TimeSpan ts = TimeSpan.Parse((string)s);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x.milliseconds = (int)ts.TotalMilliseconds;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return x;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override string ToString()&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return TimeSpan.FromMilliseconds(this.milliseconds).ToString();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public UDTTIME Addtime(UDTTIME o)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (o.IsNull)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Null;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.milliseconds += o.milliseconds;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return this;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool IsNull&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Put your code here&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return m_Null;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static UDTTIME Null&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UDTTIME h = new UDTTIME();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; h.m_Null = true;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return h;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ahora desde Visual Studio haremos el deploy hacia el servidor que nos habíamos conectado, para ello debemos ir al solution Explorer y hacer el Deploy pulsando el botón alterno del Mouse sobre el nombre de la solución.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Luego de hacer el deploy (solo demorara unos segundos) entraremos al Management Studio en el cual realizaremos las pruebas con nuestro nuevo tipo de dato.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Primero crearemos una tabla con nuestro nuevo tipo de datos&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;USE ADVENTUREWORKS&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;CREATE TABLE TIMES&lt;/p&gt;
&lt;p&gt;(&lt;/p&gt;
&lt;p&gt;&amp;nbsp; id int,&lt;/p&gt;
&lt;p&gt;&amp;nbsp; [htime] UDTTIME NULL&lt;/p&gt;
&lt;p&gt;)&lt;/p&gt;
&lt;p&gt;GO &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Luego insertaremos algunos valores &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;INSERT TIMES VALUES (1, &amp;#39;00:01:20&amp;#39;) &lt;/p&gt;
&lt;p&gt;INSERT TIMES VALUES (3, &amp;#39;16:30&amp;#39;) &lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Y por ultimo veremos como han quedado en nuestra tabla, aquí usaremos el ToString para que el resultado sea legible para un usuario &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;SELECT Id, HTIME.ToString() AS TIME&lt;/p&gt;
&lt;p&gt;FROM TIMES&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ahora en nuestra siguiente prueba trataremos de usar una suma de milisegundos a una hora determinada&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;DECLARE @Hours1 UDTTIME&lt;/p&gt;
&lt;p&gt;SET @Hours1 = &amp;#39;10:00&amp;#39; &lt;/p&gt;
&lt;p&gt;DECLARE @Seconds UDTTIME&lt;/p&gt;
&lt;p&gt;SET @Seconds = &amp;#39;00:00:10&amp;#39; &lt;/p&gt;
&lt;p&gt;SET @Hours1 =&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp; @Hours1.Addtime(@Seconds)&lt;/p&gt;
&lt;p&gt;SELECT @Hours1.ToString()&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ya disponemos de nuestro tipo de datos Hora que SQLServer por default no lo trae J. &lt;/p&gt;
&lt;p&gt;Se podrían seguir agregando métodos al mismo como por ej.: Restar horas, tener un método para indicar el total de horas que representa un time, etc.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Cabe mencionar que cuando hemos hecho el Deploy de nuestro objeto SQLServer lo introduce dentro de la base de datos con lo cual si se hace un Backup / Restore se mantendrán todos los Assemblies.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Hacer el deploy sin disponer de Visual Studio 2005&lt;/h1&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;No es una condición disponer de Visual Studio para poder hacer objetos CLR dentro de SQL2005, de hecho con un editor de textos simples y desde líneas de comando se puede resolver. En esta sección veremos los pasos necesarios para hacer este deploy sin el uso de visual Studio, tomaremos el código completo que hemos generado anteriormente y lo transformaremos en una dll con el SDK de .NET, para ello necesitaremos ejecutar el siguiente comando desde la línea de comandos&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;csc /t:library udttime.cs&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ahora debemos acceder a nuestro Management Studio.&lt;/p&gt;
&lt;p&gt;Para no generar confusión con lo anteriormente realizado crearemos una nueva base de datos.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;USE MASTER&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;CREATE DATABASE TIME1&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Nuestro siguiente paso será crear el Assembly en nuestra nueva base de datos, para ello usaremos nuevas sentencias de TSQL&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;USE TIME1&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;CREATE ASSEMBLY UDTTIME&lt;/p&gt;
&lt;p&gt;FROM &amp;#39;C:\UDTTIME.dll&amp;#39;&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Continuaremos creando el tipo de datos indicándole que el origen es un assembly &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;CREATE TYPE [dbo].[UDTTIME]&lt;/p&gt;
&lt;p&gt;EXTERNAL NAME [UDTTIME].[UDTTIME]&lt;/p&gt;
&lt;p&gt;GO&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Nota: No confundir la palabra EXTERNAL con que la .dll este dentro o fuera del motor, siempre estará dentro y ese paso se realizo cuando hemos ejecutado el &amp;quot;CREATE ASSEMBLY&amp;quot;, el External en este caso (al igual que cuando creamos un Store Procedure , User Define Function, Aggregate Function o Trigger) indica que el código de ese objeto es un assembly y no código TSQL&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Por ultimo paso nos quedaría probar el tipo de datos UDTTIME, para lo cual ejecutaremos el siguiente código:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;DECLARE @TIME1 UDTTIME&lt;/p&gt;
&lt;p&gt;SET @TIME1 = &amp;#39;20:50:00&amp;#39;&lt;/p&gt;
&lt;p&gt;SELECT @TIME1.ToString()&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Conclusiones finales:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;La inclusión del CLR dentro del motor de base de datos ha generado muchas discusiones entre los distintos especialistas, sin ninguna duda que es una feature muy importante pero hay que ser cuidadoso en como se la utiliza. Siempre es recomendado realizar con TSQL y solo dejar para CLR aquellos tipos de objetos que no se pueden crear con TSQL (como por ej. el que vimos en este articulo) o para aquellas operaciones donde el procesamiento de calculo pueda ser un problema resolver con este ultimo.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1107328" width="1" height="1"&gt;</content><author><name>maxiaccotto</name><uri>http://msmvps.com/members/maxiaccotto/default.aspx</uri></author><category term="CLR" scheme="http://msmvps.com/blogs/maxiaccotto/archive/tags/CLR/default.aspx" /></entry></feed>