PHP y Windows

Mayo 13, 2009 :: Posted by - Emilio Torrens :: Category - , ,

php_lab

No por programar en PHP tienes que estar casado con Linux pero la verdad es que eso es lo que suele pasar, nosotros mismos hemos tenido proyectos con la parte servidora corriendo en Windows, SQLServer e IIS y el UI en PHP en Linux obligando al cliente a mantener dos tipos de servidores con los problemas y gastos que puede generar eso.

El otro día ya estuve escribiendo sobre las ventajas del PHP, rápido y sencillo (por no hablar de la cantidad de programadores que puedes encontrar), por lo que no es descabellado plantear un proyecto con el UI en web en PHP mientras toda la parte servidora la tienes en .NET, con SQLServer como base de datos e IIS como servidor de aplicaciones.

La gente de Microsoft ha preparado un KIT de entrenamiento para los programadores de PHP, en este KIT tienes ejemplos y documentación para usar IIS y SQLServer desde PHP, lo puedes descargar desde aquí y encontraras:

PHP & SQL Server Demos.
Integrating SQL Server Geo-Spatial with PHP.
SQL Server Reporting Services and PHP.
PHP & SQL Server Hands On Labs.
Introduction to Using SQL Server with PHP.
Using Full Text Search over Office Documents in PHP.
PHP on Windows Hands On Labs.
IIS Access Control Features for PHP.
Using IIS 7.0 Media Features in a PHP Application.
Troubleshooting PHP.
Migrating PHP Applications to IIS 7.0.

A disfrutarlo :)

LINQ to SQL, orderby y Take

Mayo 12, 2009 :: Posted by - Emilio Torrens :: Category - , , ,

Con LINQ 2 SQL y usando Take, es realmente sencillo obtener los últimos o los primeros registros de una Tabla, simplemente tenemos que ordenarla como nos interese con el order by y usar el método Take para indicar cuantos registros queremos.

Aquí dejo un ejemplo para coger los últimos registros de una tabla.

   public List<object> GetLastRecords(int NoOfRecords)
        {
            var records =
                (from r in DataClassesDataContext.Table
                 orderby r.Pk descending select r).Take(NoOfRecords);

            List<object> Result = new List<object>();

            foreach (Record record in records)
            {
                Result.Add(records);
            }

            return Result;
        }

SQLServer 2008 Disponible

Septiembre 24, 2008 :: Posted by - Emilio Torrens :: Category -

Me acaba de llegar el mail desde MS, SQL Server 2008 ya esta disponible ;)

El pasado 6 de Agostoanunciaban la RTM (Release to Manufacturing) de Microsoft SQL Server 2008. ¡Y ya está disponible para que tus clientes puedan sacarle todo el partido!
Es una plataforma de datos fiable, productiva e inteligente con la cual ya pueden gestionar las aplicaciones de misión crítica más exigentes, reducir el tiempo y el coste tanto de desarrollo como de administración y facilitar la información necesaria de forma más ágil para la toma de decisiones.

Ahora con SQL Server 2008 podrán gestionar cualquier tipo de dato, en cualquier sitio y en cualquier momento: datos espaciales, imágenes, música y archivos gestionados de forma coherente, integrada y segura.

Ediciones de SQL Server 2008:
Además de las ya existentes con SQL Server 2005 (Enterprise, Standard, Workgroup, Developer, Express y Compact), con el lanzamiento de SQL Server 2008 se introduce una nueva edición:  SQL Server 2008 Web Edition, específicamente diseñada para entornos web de alta disponibilidad que se ejecutan sobre Windows Server. Ideal para disponer de aplicaciones web con costes reducidos y ofrecer soluciones de hosting para los clientes.

Para más información: http://www.microsoft.com/sqlserver/2008/en/us/editions.aspx

Profiling SQL CLR procedures con AQTime

Junio 11, 2008 :: Posted by - Emilio Torrens :: Category -

Intentando mejorar el rendimiento de unos procedimientos almacenados CLR que utilizamos en un proyecto hemos dado con esta herramienta que nos ha facilitado mucho las cosas. Podéis descargaros una versión de prueba desde aquí.

Aqtimebanner

Y aquí tenéis los pasos necesarios para poder analizar procedimientos almacenados CLR.

Métodos Anónimos y SQLCLR

Noviembre 20, 2007 :: Posted by - Emilio Torrens :: Category - ,

Estaba escribiendo unos procedimientos almacenados SQLCLR, usaba algunos delegados para filtrar Listas y al intentar implementar la dll en el Servidor SQL obtenía, aunque el compilador no se quejaba de nada al generar, este error:

Error 2 Error de CREATE ASSEMBLY porque el tipo ‘StoredProcedures’ del ensamblado safe ‘NameSpace.MyClase’ tiene un campo estático ‘<>9__CachedAnonymousMethodDelegate1′. Los atributos de campos estáticos de ensamblados safe deben estar marcados como readonly en Visual C#, ReadOnly en Visual Basic o initonly en Visual C++ y el lenguaje intermedio. NameSpace.MyClase

La solución es marcar la Clase con el Atributo [System.Runtime.CompilerServices.CompilerGenerated]

[System.Runtime.CompilerServices.CompilerGenerated]
public partial class StoredProcedures
{
    [SqlProcedure]
    public static void MyProcedure(SqlChars XmlRQ)
    {}
}

Si tienes la clase marcada con ese atributo ya puedes usar delegados.

Microsoft SQL Server 2008 CTP y Visual Studio 2005 Support for SQL Server 2008 CTP

Noviembre 20, 2007 :: Posted by - Emilio Torrens :: Category - ,

Con tanto revuelo con el VS 2008 y el framework 3.5 nos hemos olvidado de algunas cosas.

Se ha liberado el CTP de Noviembre de SQL Server 2008 y además se ha liberado el CTP del soporte de SQL2008 en VS 2005

Explicación visual de SQL Joins

Octubre 23, 2007 :: Posted by - Emilio Torrens :: Category -

Un artículo en Coding Horror que me ha gustado mucho que explica de forma intuitiva y gráfica los joins en SQL.

 A Visual Explanation of SQL Joins

Desencadenadores en SQL Server

Junio 01, 2007 :: Posted by - Emilio Torrens :: Category -

Podemos escribir desencadenadores para INSERT, UPDATE, DELETE y UPDATE OF.

INSERT se dispara al insertar un nuevo registro
UPDATE se dispara al modificar un registro
DELETE se dispara al borrar un registro
UPDATE OF se dispara al modificar una columna concreta de un registro

El desencadenador puede ser para uno de los eventos o para todos a la vez.

La manera de crear un nuevo trigger en el SQL es la siguiente:

CREATE TRIGGER [MiTrigger] ON [Tabla] —Nombre del trigger y a que tabla afectara
FOR INSERT, UPDATE, DELETE  —Los eventos en los que queremos que se dispare
AS
— Aquí  ponemos el código

Para que se dispare al actualizar una columna especifica

CREATE TRIGGER [MiTrigger] ON [Tabla]
FOR UPDATE OF NombreDeColumna  — La columna que tiene que ser modificada para que el evento se dispare
AS
— Aquí  ponemos el código

Desde los triggers tenemos acceso a dos tablas virtuales del SQL con las cuales podemos saber los valores del registro que 
dispara el trigger, estas tablas son Inserted y Deleted.

Estas tablas funcionan de la siguiente manera.

INSERT: Tenemos los valores del registro en la tabla Inserted.
UPDATE: Los valores antiguos los encontramos en Deleted, los nuevos en Inserted.
DELETE: Tenemos los valores del registro en la tabla Deleted.

Para acceder a estos valores, lo podemos hacer de la siguiente manera, cambiando Inserted por Deleted según el trigger y
el valor al que queramos acceder:

DECLARE @Id int
SELECT @Id = (SELECT Id FROM Inserted)

Podemos abortar transacciones desde los triggers, para eso disponemos de RollBack Tran, usándolo podemos abortar
la transacción desde el trigger y lanzar un error al cliente con RAISE ERROR, además, igual que en los procedimientos,
la variable @@error contendrá el numero, si lo hay, del ultimo error.

IF @@error <>  0 BEGIN
RollBack Tran
RAISE  ERROR (Error ,16, 1)
END

Por último es importante saber que, al escribir el código en los desencadenadores no podemos usar las siguientes funciones:


ALTER DATABASE
CREATE DATABASE
DROP DATABASE
LOAD DATABASE
RESTORE DATABASE
DISK INIT
DISK RESIZE
LOAD LOG
RECONFIGURE LOG
RESTORE LOG

ASP.NET, IIS, SQL Server 2005 y Cache de Datos

Mayo 27, 2007 :: Posted by - Emilio Torrens :: Category - , ,

Para activar el cache de datos del SQL en el IIS, debemos ejecutar varios comandos en la consola, encontraremos el aspnet_regsql.exe en la carpeta del framework.

Para registrar el servidor SQL:

  • aspnet_regsql.exe -S "NombreDelServidorSql" -E -d "NombreDeLaBaseDeDatos" -ed

Para cada una de las tablas que queramos cachear:

  • aspnet_regsql.exe -S "NombreDelServidorSql" -E -d "NombreDeLabaseDeDatos" -et -t "NombreDeLaTabla"

Para poder usar el cache en nuestro servicio o aplicacion ASP.NET debemos añadir una seccion en el Web.config

<system.web>
    <caching>
      <sqlCacheDependency enabled="true" pollTime="1000" >
        <databases>
          <add name="AliasDeLaBaseDeDatos" connectionStringName="ClaveDeLaConnecionString" />
        </databases>
      </sqlCacheDependency>
    </caching>
</system.web>

En esta sección definimos el pollTime que es el intervalo, en milisegundos ,en que debe ir a comprobar si las tablas han cambiado, los demas campos creo que estan claros.

Este tema del pollTime no esta muy claro, ya que, aunque la documentacion dice lo que os he puesto, con las pruebas que hice comprobe que el sistema trabaja por notificacion de cambios, osea que vacia el cache cuando detecta que han cambiado los datos …

Una vez configurado el IIS y el web.config de la Aplicación vamos al codigo.

Podemos crear dependencia del cache sobre una tabla con:

SqlCacheDependency cacheDepen = new SqlCacheDependency("AliasDeLaBaseDeDatos", "NombreDeLaTabla");

O podemos crear dependencia sobre varias tablas con:

SqlCacheDependency cacheDepen1 = new SqlCacheDependency("AliasDeLaBaseDeDatos", "NombreDeLaTabla1");

SqlCacheDependency cacheDepen2 = new SqlCacheDependency("AliasDeLaBaseDeDatos", "NombreDeLaTabla2");

AggregateCacheDependency aggDep = new AggregateCacheDependency();

aggDep.Add(cacheDepen1, cacheDepen2);

Ya que el objecto Cache soporta ambos al crear una entrada:

_miCache.Add(key, result, cacheDepen ,

Cache.NoAbsoluteExpiration,Cache.NoSlidingExpiration, CacheItemPriority.Default, null);

ó

_miCache.Add(key, result, aggDep,

Cache.NoAbsoluteExpiration,Cache.NoSlidingExpiration, CacheItemPriority.Default, null);

Si lo que cacheais es el resultado de una sentencia SQL, no hay mayor complicacion, podemos usar como Clave (Key) la misma sentencia o su HashCode, pero si lo que cacheamos son resultados que como peticion tienen clases de parametros, ya es otro tema.

Con el segundo supuesto, para la clave del Cache (key) empeze utilizando el GetHashCode de la clase de peticion, pero me di cuenta de que no funciona para esto, para diferencias istancias de la misma clase de peticion con los mismos valores obtienes diferentes HashCode, asi que para la clave, en este caso, os recomiento utilizar el HashCode de la string del Xml que resulta de serializar la clase, esa fue la unica manera de que me funcionara bien.

Para recuperar los datos del cache simplemente:

object

cachedData = __miCache.Get(key);

si el resultado es null, buscar los datos y meterlos en el Cache para la proxima vez :)

Mas información sobre el tema en MSDN en la web del Guille o en ASP.NET