tag:blogger.com,1999:blog-61971986169045170162024-02-06T21:00:18.469-08:00NET DeveloperJuan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.comBlogger47125tag:blogger.com,1999:blog-6197198616904517016.post-81298925954885171652013-04-16T04:21:00.000-07:002013-04-16T04:33:20.770-07:00Trabajando con hilos en C# - Working with threads in C#Cuando alguien está desarrollando aplicaciones de escritorio, las cuales cada vez son menores ya que la mayoría de aplicaciones que se desarrollan hoy en día son Web, a menudo se encuentra con que un algoritmo tarda un poco más de la cuenta, con el resultado de que bloquea el proceso y por una parte no te deja hacer nada más con la aplicación, mientras que por otro lado parece que se haya quedado colgada, cosa que puede dar problemas porque el usuario cierre la aplicación, mate el proceso o cualquier otra acción similar. Por ello siempre se recomienda el uso de hilos o threads.<br />
<br />
Como hacía bastante tiempo que no desarrollaba aplicaciones de escritorio el tema de los threads no lo tenía muy fresco, por lo que tuve que buscar algo de información para pequeños detalles que no recordaba. Los resultados los encontré en diferentes sitios, por eso me animé a reunirlos todos en este post, por si le pudiera servir a alguien de ayuda en un futuro.<br />
<br />
Crear y lanzar un nuevo thread es fácil:<br />
<br />
<blockquote class="tr_bq">
<pre>public class Simple
{
public static int Main()
{
Console.WriteLine("Thread Start/Stop/Join Sample");
// Create the thread object, passing in the Alpha.Beta method
// via a ThreadStart delegate. This does not start the thread.
<b>Thread oThread = new Thread(new ThreadStart(this.Beta));</b>
// Start the thread
<b>oThread.Start();</b>
// Spin for a while waiting for the started thread to become
// alive:
while (!oThread.IsAlive);
// Put the Main thread to sleep for 1 millisecond to allow oThread
// to do some work:
Thread.Sleep(1);
// Request that oThread be stopped
oThread.Abort();
// Wait until oThread finishes. Join also has overloads
// that take a millisecond interval or a TimeSpan object.
oThread.Join();
Console.WriteLine();
Console.WriteLine("Alpha.Beta has finished");
try
{
Console.WriteLine("Try to restart the Alpha.Beta thread");
oThread.Start();
}
catch (ThreadStateException)
{
Console.Write("ThreadStateException trying
to restart Alpha.Beta. ");
Console.WriteLine("Expected since aborted threads
cannot be restarted.");
}
return 0;
}
}</pre>
</blockquote>
<br />
En el código anterior tenéis, además, formas de pausar o detener un hilo.<br />
Al crear el hilo hemos puesto this.Beta porque el método al que llamamos está en nuestra clase. Si el método al que queremos llamar se encontrara en otra clase deberíamos poner su nombre primero:<br />
<br />
<blockquote class="tr_bq">
<pre><b> Thread oThread = new Thread(new ThreadStart(Classname.Beta));</b></pre>
</blockquote>
<br />
<br />
<br />
Bueno, hasta aquí todo sencillo. Ahora toca saber cómo pasarle parámetros al método al que llamamos. Olvidaos de ParameterizedThreadStart, con esta forma podréis pasarle múltiples parámetros:<br />
<span style="color: #990000;"><span class="v11"><span class="v11" id="lblDescription"><span style="font-family: Courier; font-size: small;"></span></span></span></span><br />
<blockquote class="tr_bq">
<pre><span class="v11"><span style="font-family: Courier; font-size: small;"><code><span class="kwd">string</span><span class="pln"> filename </span><span class="pun">=</span><span class="pln"> </span><span class="pun">...</span><span class="pln">
</span><span class="typ">Thread</span><span class="pln"> thread </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Thread</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=></span><span class="pln"> download</span><span class="pun">(</span><span class="pln">filename</span><span class="pun">));</span></code> </span></span></pre>
<pre><span class="v11"><span style="font-family: Courier; font-size: small;">thread.Start(); </span></span></pre>
</blockquote>
<br />
<br />
<br />
Y de momento es todo por hoy. En un próximo artículo explicaré cómo poder acceder a esos objetos que quedan bloqueados por el hilo principal y nos traen de cabeza.David Bernad "Berni"http://www.blogger.com/profile/08344271768217495109noreply@blogger.com3tag:blogger.com,1999:blog-6197198616904517016.post-65006623788921220962012-06-15T03:58:00.000-07:002013-04-16T04:25:11.334-07:00Cómo obtener las variables de entorno de Windows con C#<div class="separator" style="clear: both; text-align: center;">
<a href="http://chikasvip.net/img_pub/logo_windows_7.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://chikasvip.net/img_pub/logo_windows_7.png" width="100" /></a></div>
Otro caso con el que me he enfrentado recientemente, cómo crear o copiar archivos a una ruta física con tu servicio web pero haciéndolo portable para cualquier servidor con IIS. Pues la solución fue más sencilla de lo que pensaba. Gracias a un compañero que me sugirió utilizar las variables de entorno, conseguí acceder fácilmente a mi carpeta del IIS creando una variable de entorno y accediendo a ella con C#.<br />
<br />
<br />
Las variables de entorno son aquellas que nos ofrecen un "atajo" para acceder a algunos directorios del sistema, como Archivos de Programa, simplemente ejecutando en la herramienta de Ejecutar o en la barra de direcciones en una ventana el siguiente código:<br />
<blockquote class="tr_bq">
<span style="color: #990000;"><i>%ProgramFiles%</i></span></blockquote>
Pues bien, yo me creé la variable %iisdir% para que me abriera /Inetpub/wwwroot/ y así instalar ahí lo que necesitaba.<br />
<br />
Para acceder a las variables de entorno desde C# hay que hacer lo siguiente:<br />
<br />
Primero añadimos el siguiente using:<br />
<b>using System.Collections;</b><br />
<br />
Luego empezamos a obtener los valores que necesitamos:<br />
<br />
<blockquote class="tr_bq">
<span style="background-color: white;"><span style="color: #38761d;">//Ruta hasta la carpeta System32 de Windows</span></span><br />
<b>Console.WriteLine(Environment.SystemDirectory);</b><br />
<br />
<span style="background-color: white;"><span style="color: #38761d;">//Nombre de la máquina</span></span><br />
<b>Console.WriteLine(Environment.MachineName);</b><br />
<br />
<span style="background-color: white;"><span style="color: #38761d;">//Ruta del directorio desde donde se está trabajando (Esto ya lo utilizamos en un anterior post del blog)</span></span><br />
<b>Console.WriteLine(Environment.CurrentDirectory);</b><br />
<br />
<span style="background-color: white;"><span style="color: #38761d;">//Sistema operativo y versión</span></span><br />
<b>Console.WriteLine(Environment.OSVersion.ToString());</b><br />
<br />
<span style="background-color: white;"><span style="color: #38761d;">//Todas las variables de entorno y sus valores respectivos</span></span><br />
<b>IDictionary variablesEntorno = Environment.GetEnvironmentVariables();</b><br />
foreach (DictionaryEntry de in variablesEntorno)<br />
{<br />
Console.WriteLine(de.Key+": "+de.Value);<br />
} <br />
<br />
<div>
<span style="background-color: white;"><span style="color: #38761d;">//Y para obtener una en concreto de la cual conoces la clave, el ejemplo que yo utilicé, %issdir%:</span></span></div>
<div>
<b>Console.WriteLine(Environment.GetEnvironomentVariable("issdir"));</b></div>
</blockquote>
<div>
<br /></div>
<div>
<br /></div>
<div>
Con esto solucioné mi problema y pude acceder a ese directorio fácilmente, eso sí, <b>después de reiniciar</b>, porque hasta que no lo hice la aplicación no reconocía mi nueva variable de entorno.</div>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht70Dnie7miM1St-B9O8RZtURFRTCpTBqKobos7VvNHDKcIAdZum88i5rfvwtZFl25xay2Iiq2Y5nZ95LR0EwPpjtjP0hB3ervV8BAZ4niXoSkaZdnCJR7HWA_OokT4iacg6ZMtocJ408/s1600/C_Sharp.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht70Dnie7miM1St-B9O8RZtURFRTCpTBqKobos7VvNHDKcIAdZum88i5rfvwtZFl25xay2Iiq2Y5nZ95LR0EwPpjtjP0hB3ervV8BAZ4niXoSkaZdnCJR7HWA_OokT4iacg6ZMtocJ408/s200/C_Sharp.png" width="150" /></a></div>
<br /></div>
<div>
<span style="font-size: x-small;">Fuente: <a href="http://reisbel.blogspot.com.es/2010/02/como-obtengo-las-variables-de-entorno.html">Blog de Reisbel</a></span></div>
David Bernad "Berni"http://www.blogger.com/profile/08344271768217495109noreply@blogger.com1tag:blogger.com,1999:blog-6197198616904517016.post-2167164020719186082012-06-13T11:01:00.000-07:002012-06-13T11:04:23.411-07:00Obtener el directorio de ejecución de tu aplicación con C# (equivalencia a App.Path)<span style="font-family: Arial, Helvetica, sans-serif;">Hace años ya me enfrenté a este problema y en su día lo solucioné, pero hoy me he vuelto a enfrentar a él y no recordaba cómo era. Lo que sí recordaba era que había varias formas, pero sólo una de ellas era la idónea para mí, para lo que necesitaba hacer en ese momento. Pues bien, ahora me encuentro en una situación similar a la de entonces y lo que necesito es obtener la ruta de mi aplicación, pero en un formato adecuado para crear/modificar/eliminar archivos allí, es decir, para usar la librería System.IO.File.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Una forma para conocer la ruta es la que más se encuentra si "googleas" un poco:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<blockquote class="tr_bq">
<span style="color: #cc0000; font-family: Arial, Helvetica, sans-serif;">System.Reflection.Assembly.GetExecutingAssembly(). GetName().CodeBase</span></blockquote>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 20px;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 20px;">Pero te devuelve la ruta en este formato: </span><br />
<blockquote class="tr_bq">
<span style="color: #073763;"><span style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 20px;"><i>file://C:/Users/...</i></span></span></blockquote>
<span style="font-family: Arial, Helvetica, sans-serif;">Con lo cual no es útil para lo que yo lo necesito. Entonces si lo que quiero es obtener la ruta en este formato:</span><br />
<blockquote class="tr_bq">
<i><span style="color: #073763; font-family: Arial, Helvetica, sans-serif;">C:\Users\Admin\...</span></i></blockquote>
<span style="font-family: Arial, Helvetica, sans-serif;">Tengo que hacerlo de esta forma:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<blockquote class="tr_bq">
<span style="color: #cc0000; font-family: Arial, Helvetica, sans-serif;">Environment.CurrentDirectory</span></blockquote>
<span style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 20px;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Y con esto ya tengo solucionado el problema. Es similar al <i><b><span style="color: #073763;">App.Path</span></b></i> de Visual Basic, fácil de recordar y útil para usar la ruta.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Espero que la próxima vez que tenga que buscar esto mire antes en mi blog :)</span>David Bernad "Berni"http://www.blogger.com/profile/08344271768217495109noreply@blogger.com3tag:blogger.com,1999:blog-6197198616904517016.post-45930518556159081062012-06-01T02:27:00.000-07:002013-01-10T15:06:09.497-08:00Cómo descomprimir archivos .zip en .net (C#)Después de dos años sin ser actualizado este blog por los miembros del equipo, en concreto unos cuatro o cinco años por mi parte, vuelvo a la carga con un nuevo post.<br />
<br />
Debido a cambios en mi vida laboral, después de unos cuantos años vuelvo a retomar la programación en C#, por lo que tengo que refrescar unas cosas y aprender otras nuevas. En la parte de aprender nuevas hoy he descubierto <strong>cómo se puede descomprimir un archivo .zip con .NET</strong>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://consejoguia.com/wp-content/uploads/2010/07/C%C3%B3mo-abrir-los-archivos-Zip-protegidos-con-contrase%C3%B1a.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" rba="true" src="http://consejoguia.com/wp-content/uploads/2010/07/C%C3%B3mo-abrir-los-archivos-Zip-protegidos-con-contrase%C3%B1a.gif" width="200" /></a></div>
Es muy sencillo, tan solo necesitamos la librería open source SharpZipLib, que podéis encontrar en este enlace <span style="-webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: white; color: #333333; display: inline !important; float: none; font: 12px/19px verdana, tahoma, arial, sans-serif; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"> </span><a href="http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx" style="-webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: white; border-bottom: rgb(153,102,51) 1px solid; color: #265e15; font: 12px/19px verdana, tahoma, arial, sans-serif; letter-spacing: normal; margin: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx</a>.<br />
<br />
Hay que descomprimir el archivo y copiar la .dll en algún directorio de tu proyecto. En concreto he usado la librería que se encuentra en la carpeta "<em>net-20</em>". Entonces agregas la referencia a esta librería (Botón derecho -> Agregar Referencia -> Examinar) y usas un sencillo método:<br />
<br />
<blockquote class="tr_bq">
<span style="color: #cc0000;">FastZip fZip = new FastZip();</span><br />
<span style="color: #cc0000;">fZip.ExtractZip(@”C:\miarchivo.zip”, @”C:\Temp”, “”);</span></blockquote>
El primer argumento es la ruta completa del archivo a descomprimir. El segundo argumento es la ruta donde queremos descomprimir el contenido del archivo. El tercer argumento, que en este caso está vacío, se puede usar para poner expresiones regulares que indiquen qué tipo de archivos queremos descomprimir; si lo dejamos en blanco se extraerán todos los archivos. Un ejemplo de expresión regular para descomprimir sólo las imágenes: <strong>“(?i)^.*(?:(?:.jpg)|(?:.png))$</strong>” . <br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.igarol.org/imagenes/archivo_zip.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" rba="true" src="http://www.igarol.org/imagenes/archivo_zip.gif" /></a></div>
<br />
<span style="font-size: x-small;">Fuente: </span><span style="font-size: x-small;"><a href="http://robertoyudice.wordpress.com/2009/05/10/como-descomprimir-archivos-zip-en-net-c/">http://robertoyudice.wordpress.com/2009/05/10/como-descomprimir-archivos-zip-en-net-c/</a></span><br />
<br />
<b>Edito</b>: Como bien indican en los comentarios, se me olvidó comentar que hay que añadir el "using" de la librería al principio:<br />
<blockquote class="tr_bq">
<span style="color: #cc0000;">using ICSharpCode.SharpZipLib.Zip;</span></blockquote>
Gracias por vuestros comentarios.David Bernad "Berni"http://www.blogger.com/profile/08344271768217495109noreply@blogger.com7tag:blogger.com,1999:blog-6197198616904517016.post-44268921836214259162010-02-02T04:55:00.000-08:002010-02-02T04:56:47.201-08:00Comparación de características entre versiones de SQLServer 2005MSDN: <a href="http://www.microsoft.com/Sqlserver/2005/en/us/compare-features.aspx">http://www.microsoft.com/Sqlserver/2005/en/us/compare-features.aspx</a>Juan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-48820142344306903012010-02-02T04:51:00.000-08:002010-02-02T04:55:08.994-08:00Actualizar una base de datos de SQL Server 2000 a SQL Server 2005Para actualizar una base de datos de SQL2000 a SQL2005 bastará con destatacharla del servidor 2000 y atacharla al servidor de 2005.<br />Tras esto habrá que ejecutar el comando:<br /><br />DBCC UPDATEUSAGE<br /><br />MSDN: <a href="http://msdn.microsoft.com/es-es/library/ms189625.aspx">http://msdn.microsoft.com/es-es/library/ms189625.aspx</a>Juan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-66625154520520524672010-01-19T13:59:00.001-08:002010-01-19T14:13:48.966-08:00Método IsDate como extensor de String<div align="justify">Tras leer un árticulo en la web sobre métodos extensores en Visual Studio 2008 y para probar la facilidad de uso de estos he implementado en método IsDate, extensor de String que siempre viene bien para comprobar las cadenas que son fechas válidas. El código quedaría como sigue:<br /><br />using System;<br /><br />/// <summary><br />/// Clase que implementa métodos extensores.<br />/// </summary><br />public static class Extensores<br />{<br />/// <summary><br />/// Determina si una cadena es o no una fecha válida.<br />/// </summary><br />/// <param name="cadena">Cadena a validar.</param><br />/// <returns><br />/// <c>true</c> si la cadena es una fecha válida, sino <c>false</c>.<br />/// </returns><br />public static bool IsDate(this String cadena)<br />{<br />DateTime d;<br />return DateTime.TryParse(cadena, out d);<br />}<br />}<br /><br />Es decir basta con crear una clase estática con una función estatica IsDate con un parámetro (this String cadena). Con esta nomenclatura le estamos diciendo que el metodo extensor es para la clase String.</div><div align="justify"> </div><div align="justify">He usado la funcion TryParse de DateTime porque según he leido es más eficiente que usar bloques try - catch - finally.</div><div align="justify"> </div><div align="justify">No es muy dificil de implementar pues y el uso seria muy facil puesto que ahora nuestra clase String posee un metodo nuevo al que podremos acceder facilmente:</div><div align="justify"> </div><div align="justify">String.Empty.IsDate()</div><div align="justify"> </div><div align="justify">Esa llamada se evalua como falso ya que la cadena vacia no es una fecha válida.</div>Juan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-8030682185565898522009-08-18T09:13:00.000-07:002009-08-18T09:17:55.988-07:00Obtener la url de tu página web con ASPPara crear un link a la hora de enviar un correo electronico automaticamente tras el registro de un usuario necesitaba obtener la url completa de la pagina a la que debia de hacer referencia dicho link. Tras googlear un poco encuentre esta solución:<br /><br />Request.Url.Authority<br /><br />Esta linea de codigo c# obtiene la direccion base de la web por ejemplo en mi caso, con el servidor de desarrollo de NET me devuelve esto:<br /><br />localhost:1623<br /><br />A eso le concatenamos lo que creamos necesario.Juan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-39287688656859546992009-08-10T02:58:00.001-07:002009-08-10T03:01:10.023-07:00Carácter de escape para las comillas simples en T-SQLEsta mañana me ha surgido la necesidad de generarme codigo mediante una select y precisaba que esta select generara otras selects, tras un ratillo de busqueda he encontrado que para generar unas comillas simple basta con poner dos.<br /><br />Ej:<br />select 'insert into modulo (nombre, ruta) values (''' + nombre + ''', ''' + ruta +''')' from ModuloJuan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com3tag:blogger.com,1999:blog-6197198616904517016.post-58238049888718027432009-07-26T12:21:00.000-07:002009-07-26T12:28:39.360-07:00Alternar bloques de comentarios en C#Magnífico truco de mi compañero <a href="http://sharepointeando.blogspot.com/">A.J. Busquiel</a> el que aquí publico, una forma de alternar dos bloques de comantarios para, cuando andamos haciendo pruebas comentando y descomentando trozos de codigo:<br /><br />//*<br /> Bloque de código 1<br />/*/<br /> Bloque de código 2<br />/**/<br /><br />Probemos en Visual Studio que quitando la primera barra (/) comentamos el primer bloque de código y dejandolo puesto comentemos el bloque 2.Juan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com1tag:blogger.com,1999:blog-6197198616904517016.post-2000618035635576212009-07-22T07:43:00.000-07:002009-07-22T07:52:36.672-07:00Silverlight con parametrosEsta mañana tenia la necesidad de compartir un pequeño control de Silverlight en varias paginas y tenia que mostrar secciones distintas según la pagina que la llamaba.<br /><br />La primera idea que tuve (y esa he aplicado) es pasarle parametros al silverlight mediante su propiedad InitParametrers tal como esto:<br /><br /><asp:Silverlight ID="Silverlight1" runat="server" Source="~/ClientBin/ComponentesSilverlight.xap" MinimuVersion="2.0.31005.0" Width="100%" Height="100%" InitParameters="pantalla=enlaces" /><br /><br />Con esta llamada al elemento Silverlight podremos obtener los parametros en el Startup de App.aspx.cs tal como sigue:<br /><br />private void Application_Startup(object sender, StartupEventArgs e)<br />{<br />string pantalla = string.Empty;<br />if(e.InitParams.Keys.Contains("pantalla")) pantalla = e.InitParams["pantalla"];<br />this.RootVisual = new Page(pantalla);<br />}<br /><br />Y pos supuesto tendremos que cambiar el constructor de la clase Page del componente Silverlight con el/los parametros que vamos a utilizar por ejemplo:<br /><br /><br />private string _pantalla;<br /><br />public Page(string pantalla)<br />{<br />InitializeComponent();<br />_pantalla = pantalla;<br />}<br /><br />Luego podremos usar la variable privada _pantalla para lo que pretendamos.Juan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-88905886044580147762009-07-21T09:26:00.000-07:002009-07-21T09:38:36.210-07:00Update para rempllazar contenido en tablas de una bdHoy tenía la necesidad de hacer unos cambios en los datos de una BD para hacer una demo y hacerla con datos reales. He googleado un poco y rapidamente he encontrado la función replace() de T-SQL paar este fin y me ha ido de maravilla. Este es el UPDATE que he utilizado para ir cambiando ciertas palabras de ciertas columnas de mi BD, espero que le sirva a alguien además de a mi:<br /><br /><span style="font-size:85%;color:#000000;">update noticia set contenido = replace(contenido, 'Florentino', 'Deportivo') where contenido like '%Florentino%'</span><br /><span style="font-size:85%;"></span><br /><span style="font-size:85%;">Documentación MSDN:</span><br /><br /><a href="http://msdn.microsoft.com/es-es/library/ms186862.aspx">http://msdn.microsoft.com/es-es/library/ms186862.aspx</a>Juan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-52448412658947079252009-07-08T01:55:00.000-07:002009-07-08T01:59:34.122-07:00Operadores ternarios en C#¿Conociais el operador <strong><em>??</em></strong> de c#?, yo no y creo que me va a encantar.<br /><br />¿Conociais el operador <strong><em>?:</em></strong>?<br /><br />Pues bien, la mejor explicación, un ejemplo:<br /><br />String cadena = null;<br />MessageBox.Show(cadena??"(null)");<br />MessageBox.Show(cadena==null?"(null)":cadena);<br /><br />Los dos MessageBox son equivalentes.Juan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-28226700625925372542009-07-07T04:01:00.000-07:002009-07-07T04:10:33.215-07:00Obtener instancias de SQLServer 2000 y 2005.Net Framework nos facilita la tarea de obtener las instancias en la red de SQLServer 2000-2005 mediante una unica linea de codigo coomo sigue:<div><br /></div><div>System.Data.DataTable dtServidores = System.Data.Sql.SqlDataSourceEnumerator.Instance.GetDataSources();</div><div><br /></div><div>Con esto obtendremos un registro por cada instancia de SQL server con cuatro columnas:</div><div><ul><li>ServerName: Nombre del servidor.</li><li>InstanceName: Nombre de la instancia del servidor. En el caso de tratarse de la instancia predeterminada estará en blanco.</li><li>IsClustered: Yes o No segun la instancia forme parte de un cluster de servidores.</li><li>Version: Versión del servidor.(8.0.x, para SQL2000 y 9.00.x para SQL 2005)</li></ul></div>Juan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-57060011740434204962009-07-06T03:49:00.000-07:002009-07-06T03:55:33.239-07:00Obtener la estructura de una tabla con T-SQLSi queremos ver la estructura de una tabla con una select, basta con consultar el catálogo. Hay una vista en information_schema.columns que tiene informacion de las columnas de todas las tablas de la BD, bastaría con filtrar por nombre de tabla con la siguiente Select:<br /><br /><br />SELECT * FROM information_schema.columns WHERE table_name = 'facturascompra'<br />GO<br /><br />Con este ejemplo obtendremos los campos de la tabla facturascompraJuan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com1tag:blogger.com,1999:blog-6197198616904517016.post-74482191709532200932009-07-02T04:18:00.000-07:002009-07-02T04:26:26.279-07:00Insertar código XML en un HTMLEn la publicación del anterior post me surgió el problema, como a muchos otros (supongo), que ya habrán solucionado, de insertar codigo XML dentro de mi post. Pues bien, la única forma de solucionarlo que encontré fué utilizar los caracteres de escape de HTML de los caracteres especiales como <, >, / ...<br /><br />Desde esta web se puede obtener la cadena que hay que copiar en el post para mostrar un xml en el:<br /><br /><a href="http://www.simplebits.com/cgi-bin/simplecode.pl?mode=process">http://www.simplebits.com/cgi-bin/simplecode.pl?mode=process</a><br /><br />Esta es una tabla con otros caracteres especiales de HTML:<br /><br /><br /><table border="1"><tbody><tr><th width="59">Carácter</th><th width="60">Código</th><th>Carácter</th><th>Código</th></tr><tr><td><</td><td>&lt;</td><td>±</td><td>&plusmn;</td></tr><tr><td>></td><td>&gt;</td><td>·</td><td>&middot;</td></tr><tr><td>¡</td><td>&iexcl;</td><td>×</td><td>&times;</td></tr><tr><td>¿</td><td>&iquest;</td><td>÷</td><td>&divide;</td></tr><tr><td>©</td><td>&copy;</td><td>¼</td><td>&frac14;</td></tr><tr><td>®</td><td>&reg;</td><td>½</td><td>&frac12;</td></tr><tr><td>™</td><td>&trade;</td><td>¾</td><td>&frac34;</td></tr><tr><td>¢</td><td>&cent;</td><td>¹</td><td>&sup1;</td></tr><tr><td>£</td><td>&pound;</td><td>²</td><td>&sup2;</td></tr><tr><td>¥</td><td>&yen;</td><td>³</td><td>&sup3;</td></tr><tr><td>€</td><td>&euro;</td><td>‰</td><td>&permil;</td></tr><tr><td>ª</td><td>&ordf;</td><td>∑</td><td>&sum;</td></tr><tr><td>º</td><td>&ordm;</td><td>∏</td><td>&prod;</td></tr><tr><td>Á</td><td>&Aacute;</td><td>√</td><td>&radic</td></tr><tr><td>á</td><td>&aacute;</td><td>∞</td><td>&infin;</td></tr><tr><td>É</td><td>&Eacute;</td><td>≈</td><td>&asymp;</td></tr><tr><td>é</td><td>&eacute;</td><td>≠</td><td>&ne;</td></tr><tr><td>Í</td><td>&Iacute;</td><td>≡</td><td>&equiv;</td></tr><tr><td>í</td><td>&iacute;</td><td>≤</td><td>&le;</td></tr><tr><td>Ó</td><td>&Oacute;</td><td>≥</td><td>&ge;</td></tr><tr><td>ó</td><td>&oacute;</td><td>Ñ</td><td>&Ntilde;</td></tr><tr><td>Ú</td><td>&Uacute;</td><td>ñ</td><td>&ntilde;</td></tr><tr><td>ú</td><td>&uacute;</td><td>Ç</td><td>&Ccedil;</td></tr><tr><td>Ü</td><td>&Uuml;</td><td>ç</td><td>&ccedil;</td></tr><tr><td>ü</td><td>&uuml;</td><td>˜</td><td>&tilde</td></tr><tr><td>&</td><td>&amp;</td><td>π</td><td>&pi;</td></tr></tbody></table>Juan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-65655733112169728342009-07-02T03:35:00.000-07:002009-07-02T23:19:00.559-07:00Acceso mediante silverlight a un Servicio Web de otro dominioPor razones de seguridad, un servicio web no se puede consumir desde Silverlight sin que se especifiquen los permisos en un archivo xml llamado clientaccesspolicy.xml.<br /><br />Un ejemplo basico de este archivo que permite al acceso desde cualquier dominio a un servicio web sería este:<br /><br /><code><br /><?xml version="1.0" encoding="utf-8"?><br /><br /><access-policy><br /><br /><cross-domain-access><br /><br /><policy><br /><br /><allow-from http-request-headers="*"><br /><br /><domain uri="*"/><br /><br /></allow-from><br /><br /><grant-to><br /><br /><resource path="/" include-subpaths="true"/><br /><br /></grant-to><br /><br /></policy><br /><br /></cross-domain-access><br /><br /></access-policy><br /></code><br /><br /><br />Tambien puede ser usado el archivo que usa Flash, crossdomain.xml, un ejemplo del cual seria:<br /><br /><code><br /><?xml version="1.0"?><br /><br /><!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"><br /><br /><cross-domain-policy><br /><br /><allow-http-request-headers-from domain="*" headers="*"/><br /><br /></cross-domain-policy><br /></code><br /><br /><br />Estos archivos deben de estar accesibles por el cliente Silverlight en la raiz de la web donde se alojan los servicios, ya que lo primero que hará Silverlight será descargase uno de estos archivos para comprobar la seguridad.Juan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-2256846689085622852009-04-14T07:44:00.000-07:002009-04-14T07:47:31.940-07:00Escritorio 3D para WindowsHay una herramienta que te instala un escritorio 3D en tu sistema operativo con el que parece que estés trabajando en el propio escritorio de tu casa, con objetos reales.<br /><br />Mirad el vídeo y flipad. Es en inglés pero algo se entiende.<br /><br /><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/eqcmPJ-oVL0&color1=0xb1b1b1&color2=0xcfcfcf&hl=en&feature=player_embedded&fs=1"><param name="allowFullScreen" value="true"><embed src="http://www.youtube.com/v/eqcmPJ-oVL0&color1=0xb1b1b1&color2=0xcfcfcf&hl=en&feature=player_embedded&fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"></embed></object><br /><br /><br />Este es el enlace de la aplicación:<br /><br /><a href="http://bumptop.com/">http://bumptop.com/</a>David Bernad "Berni"http://www.blogger.com/profile/08344271768217495109noreply@blogger.com1tag:blogger.com,1999:blog-6197198616904517016.post-46096641569633629682009-04-09T08:57:00.000-07:002009-04-09T09:04:18.367-07:00Instalación desatendia de Microsoft SQL Server 2005Para iniciar una instalacion desatendida se puede usar la siguiente linea de comandos:<br /><br />Setup.exe /qn /settings [ruta del archivo.ini]<rutadelarchivo.ini><br /><br />El archivo ini al que se hace referencia contine las opciones de instalación, con esta linea conseguiremos que se realice una instalación tal y como la definimos en el archivo ini sin ninguna intervencion del usuario.<br /><br />El DVD de instalación de SQL Server 2005 facilita una plantilla de este archivo ini, en mi caso lo encontrè en la ruta D:\SQL Server x86\Tools\Template.iniJuan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-51338027510609015792009-03-27T12:48:00.000-07:002009-03-27T12:56:28.901-07:00Transacciones en SQL ServerSintaxis: <a href="http://msdn.microsoft.com/es-es/library/ms188929.aspx">MSDN</a><br /><br />Ejemplo:<br />BEGIN TRY<br />BEGIN TRAN<br />INSERT INTO CLIENTES (ID) VALUES ('tabla1')<br />INSERT INTO CLIENTES (ID) VALUES ('tabla2')<br />INSERT INTO CLIENTES (ID) VALUES ('tabla3')<br />COMMIT TRAN<br />END TRY<br />BEGIN CATCH<br />ROLLBACK TRAN<br />SELECT ERROR_NUMBER(), ERROR_MESSAGE()<br />END CATCHJuan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-48519140065388257642009-03-27T12:28:00.000-07:002009-03-27T12:47:32.458-07:00Manejo de excepcionesEn SQL Server existen los bloques TRY-CATH para el control de excepciones.<br /><br />Sintaxis: <a href="http://msdn.microsoft.com/es-es/library/ms175976.aspx">MSDN</a><br /><br />Ejemplo:<br />BEGIN TRY<br />INSERT INTO CLIENTES (ID) VALUES ('tabla')<br />END TRY<br />BEGIN CATCH<br />SELECT ERROR_NUMBER(), ERROR_MESSAGE()<br />END CATCHJuan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-12883065654849246472009-03-27T01:54:00.000-07:002009-03-27T03:30:35.596-07:00El nuevo HTML5El HTML5 es una nueva versión del popular lenguaje HTML, que se empezó a desarrollar en 2004 en colaboración entre <a href="http://www.w3.org/html/"><abbr title="W3C HTML Working Group">W3C HTML WG</abbr></a> y <a href="http://www.whatwg.org/"><abbr title="Web Hypertext Application Technology Working Group">WHATWG</abbr></a>.<br /><br />Lo más destacable de esta nueva versión son las nuevas etiquetas que se introducen para darle un aspecto más lógico y entendible al código, y como se trata de un estándar, que pueda ser interpretado casi por igual por los navegadores más importantes, Fire Fox, Internet Explorer, Safari y Opera. No comentan nada del Google Chrome, pero es lógico porque es todavía muy nuevo y no se ha difundido lo suficiente, aunque no planteará problemas en principio, ya que lo visto hasta el momento es que interpreta las páginas de forma muy parecida a Safari o Fire Fox.<br /><br />Con estas nuevas etiquetas el uso de los difundidos <span style="font-style: italic;font-family:arial;" >div</span> se reducirá considerablemente, ya que sustituiremos los típicos <span style="font-style: italic;font-family:arial;" >< id="header"></span> y <span style="font-style: italic;font-family:arial;" >< id="footer"></span> por etiquetas <span style="font-style: italic;font-family:arial;" ><header></span> y <span style="font-style: italic;font-family:arial;" ><footer></span>. Con esto se consigue lo comentado anteriormente, un aspecto más fácilmente entendible del código de cara a un futuro mantenimeinto.<br /><br />Os muestro un ejemplo de estos cambios:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.alistapart.com/d/previewofhtml5/structure-div.gif"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www.alistapart.com/d/previewofhtml5/structure-div.gif" alt="" border="0" /></a><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.alistapart.com/d/previewofhtml5/structure-html5.gif"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www.alistapart.com/d/previewofhtml5/structure-html5.gif" alt="" border="0" /></a><br />También tendremos etiquetas nuevas para vídeo y audio, con sus correspondientes atributos.<br /><br />En <a href="http://www.alistapart.com/articles/previewofhtml5">este enlace</a> se pueden ver otros cambios de la nueva versión.David Bernad "Berni"http://www.blogger.com/profile/08344271768217495109noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-67122247098193133042009-03-26T15:19:00.000-07:002009-03-27T12:25:26.265-07:00Creacion de funcionesSon rutinas que constan de una o mas instrucciones que sirven para encapsular codigo y poder reutilizarlo, puede tomar 0 o más parámetros de entrada y devuelve un valor escalar o una tabla. Los parámetros de entrada pueden ser de cualquier tipo excepto timestamp, cursor o table.<br /><br />Sintaxis: <a href="http://technet.microsoft.com/es-es/library/ms186755.aspx">MSDN</a><br /><br />Ejemplo:<br /><br />Creación de una función escalar:<br /><br />CREATE FUNCTION BDs(@COLLATION_NAME VARCHAR(50) = NULL) RETURNS INT<br />AS<br />BEGIN<br />DECLARE @RET INT<br />IF @COLLATION_NAME IS NULL<br />SET @RET = (SELECT COUNT(*) FROM sys.databases WHERE COLLATION_NAME IS NULL)<br />ELSE<br />SET @RET = (SELECT COUNT(*) FROM sys.databases WHERE COLLATION_NAME = @COLLATION_NAME)<br />RETURN @RET<br />END<br />GO<br /><br />Creación de una funcion con valores de tabla en linea:<br /><br />CREATE FUNCTION BDs(@COLLATION VARCHAR(50)) RETURNS TABLE<br />AS<br />RETURN(SELECT * FROM SYS.DATABASES WHERE <a href="mailto:COLLATION_NAME=@COLLATION">COLLATION_NAME=@COLLATION</a>)<br />GO<br /><br />Creación de una función con valores de tabla de varias instrucciones:<br /><br />CREATE FUNCTION BDs(@COLLATION VARCHAR(50))<br />RETURNS @RET TABLE (NAME VARCHAR(50) PRIMARY KEY)<br />AS<br />BEGIN<br />IF(@COLLATION='')<br />BEGIN <br />INSERT @RET <br />SELECT [NAME] FROM SYS.DATABASES WHERE COLLATION_NAME IS NULL<br />END<br />ELSE<br />BEGIN <br />INSERT @RET <br />SELECT [NAME] FROM SYS.DATABASES WHERE COLLATION_NAME = @COLLATION<br />END<br /> RETURN<br />END<br />GOJuan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-11897635516792949702009-03-26T14:35:00.000-07:002009-03-26T15:04:06.645-07:00Procedimientos almacendados parametrizadosLos procedimientos almacenados pueden tener parámetros de entrada y de salida para comunicarse con el programa que los llama.<br /><br />Sintaxis: <a href="http://msdn.microsoft.com/es-es/library/ms187926.aspx">MSDN </a><br /><br />Ejemplo:<br />CREATE PROCEDURE BDs<br />(@COLLATION_NAME VARCHAR(50) = NULL,<br />@RET INT = 0 OUTPUT)<br />AS<br />IF @COLLATION_NAME IS NULL<br />BEGIN<br />SELECT * FROM sys.databases WHERE COLLATION_NAME IS NULL<br />SET @RET = (SELECT COUNT(*) FROM sys.databases WHERE COLLATION_NAME IS NULL)<br />END<br />ELSE<br />BEGIN<br />SELECT * FROM sys.databases WHERE COLLATION_NAME = @COLLATION_NAME<br />SET @RET = (SELECT COUNT(*) FROM sys.databases WHERE COLLATION_NAME = @COLLATION_NAME)<br />END<br />RETURN @RET + 1<br />GO<br /><br />Se crea un procedimiento almacenado que acepta un parámetro para filtrar la lista de bases de datos por el collation y retorna en un segundo parametro la cantidad de bases de datos con ese collation, como ejemplo retorna la cantidad de bases de datos mas 1 como valor de retorno.Juan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0tag:blogger.com,1999:blog-6197198616904517016.post-55207878350485003172009-03-23T14:53:00.000-07:002009-03-23T15:42:58.846-07:00Procedimientos almacendadosUn procedimiento almacenado es una colección de instrucciones con nombre de sentencias T-Sql.<br />Ventajas:<br /><br /><ul><li>Encapsula la funcionalidad de negocio y crea lógica de aplicación reutilizable.</li><li>Evita la exposición de la estructura de la BD a los usuarios.</li><li>Proporciona mecanismos de seguridad (acceso a tablas a las que no se tiene acceso real a traves de los procedimientos almacenados.)</li><li>Mejorar el rendimiento</li><li>Reducir tráfico en la red</li><li>Reducir vulneravilidad a ataques mediante instrucciones SQL incrustadas en los parámetros.</li></ul><p>Creación de procedimientos almacenados.</p><p>Sintaxis: <a href="http://msdn.microsoft.com/es-es/library/ms187926.aspx">MSDN</a></p><p>Ejemplo:</p><p>CREATE PROCEDURE BDs</p><p>AS </p><p>SELECT * FROM sys.databases</p><p>GO</p><p>Modificación de procedimientos almacenados:</p><p></p><p>Sintaxis: <a href="http://msdn.microsoft.com/es-es/library/ms189762.aspx">MSDN</a></p><p>Ejemplo:</p><p>ALTER PROCEDURE BDs</p><p>AS </p><p>SELECT * FROM sys.databases ORDER BY name</p><p>GO</p><p>Ejecución de un procedimiento almacenado:</p><p>Sintaxis: <a href="http://msdn.microsoft.com/en-us/library/ms188332.aspx">MSDN</a></p><p>Ejemplo:</p><p>Exec BDs</p><p>Eliminacion de procedimientos almacendos:</p><p>Antes de borrar cualquier procedimiento almacenado es recomendable ejecutar el procedimiento almacenado de la BD master sp_depends pare resolver si existe algun procedimiento que dempenda de este:</p><p>EXEC sp_depends @objname = N'BDs'</p><p>Sintaxis: <a href="http://msdn.microsoft.com/es-es/library/ms174969.aspx">MSDN</a></p><p>Ejemplo:</p><p>DROP PROC BDs</p>Juan Antonio Barcelo Aravidhttp://www.blogger.com/profile/15328829397794208203noreply@blogger.com0