Migrando FoxPro a Sql Server

Kevin Cox ha publicado un artículo en el Blog de Microsoft Sql Server Development Customer Advisory Team sobre su experiencia de migrar una solución FoxPro a Sql Server.

Aquí algunas de las notas acerca de los puntos a tomar en cuenta para una migración:

1. Si se tiene un tipo de datos MEMO en FoxPro deberias usar VARCHAR(MAX) en SQL Server. Podriamos usar TEXT pero sabemos que ya no va a ser utilizado en la próxima versión, y que será sustituida por VARCHAR(MAX). Y VARCHAR(MAX) tiene mejor performance.

2. Hay muchos tipos DATE en FoxPro. La decisión fue fácil de convertirlas a todos a DATETIME en SQL Server 2005. En SQL Server 2008 hay mas tipos DATE, de modo que hay que estudiar como mapear los tipos de datos FoxPro a los nuevos tipos SQL Server 2008. Los datos tipo DATETIME fueron exportados en formato de cadena usando YYYYMMDDHHMMSS.

3. En FoxPro NUMERIC(5,2) permite un rango de -99999 to 99999. En SQL Server usando la misma precision el rango es -999.99 a 999.99. Este fue el unico tipo de datos en el esquema que necesito ser alterado el nivel de tipo de datos. Entonces en SQL Server se usó NUMERIC (7,2) para conseguir el mismo rango.

4. Los campos en FoxPro de tipo LOGICAL fueron exportados como T/F o 0/1. Ellos se convirtieron en un tipo BIT data type en SQL Server o un TINYINT. TINYINT fue elegido si se van a realizar calculos sobre el campo en el futuro; p.e. SUM, AVG, etc.

El artículo completo se puede leer aquí.

Consulta con fechas

Otro problema que a veces nos causa programar contra Sql Server, es cuando se inscrustan consultas dentro del software (por eso siempre es mejor utilizar procedimientos almacenados), cosa que no es lo recomendable, pero que a veces es necesario.

En Visual Basic (versión 2005) tenía la siguiente consulta que habia armado:

Consulta1 = "Update Tabla1 Set Fecha = '" & Fecha & "' Where CodigoId=" + CodigoId.Trim

Es decir vamos a cambiar la tabla Tabla1, la fecha y lo filtramos por CodigoId. La variable Fecha es del tipo Datetime, y la obtenemos cuando el usuario elige una fecha en un Datetimepicker del formulario. No se nota bien pero se utilizan comillas simples (') para delimitar la fecha en la consulta.

Si esa consulta, tal como está la ejecutamos utilizando un SqlCommand, nos dará un error, diciendo que no se pudo efectuar la conversión de cadena a datetime.

El error se debe a que al guardar el valor del DatetimePicker en la variable Fecha, se guarda con hora también, y ese dato al parecer no permite ejecutar la consulta. Ahora solo ponemos en la consulta la parte de la fecha y el mensaje de error no volverá a salir, y la consulta se ejecutará correctamente.

Consulta1 = "Update Tabla1 Set Fecha = '" & Fecha.ToString.Substring(0, 10) & "' Where CodigoId=" + Codigo.Trim

Parece sencillo, pero me tomó unos minutos descubrir la forma de solucionarlo.

Visual Basic y Sql Server con Ado Data Control

Introducción

Este artículo es una respuesta a una petición de ayuda de un lector. Necesitaban un ejemplo acerca de como conectar Visual Basic 6.0 a Sql Server, él tiene un sistema hecho en Visual Basic que se conectaba a una base de datos Access, utilizando el Data Control. He utilizado en este ejemplo Visual Basic 6.0 (con Service Pack 6), y Sql Server 2000 (Service Pack 4).

Lamentablemente, el Data Control no permite el acceso a bases de datos Sql Server directamente, y no utilizan ADO, que es mucho más eficiente que DAO para acceder a Sql Server.

Desarrollo del Ejemplo

Se tendría que utilizar ADO Data Control (ADODC) para realizar un ejemplo lo más similar a lo que utiliza actualmente en su software. El ADODC es muy similar al Data Control, para poder utilizarlo en el proyecto, hay que agregar el componente como se ve en la imagen (hacer clic para verla).



El diseño del formulario de ejemplo es simple:



Los primeros campos, permiten al usuario ingresar el nombre del Servidor, el nombre de la base de datos, el usuario con los permisos suficientes para acceder a la base de datos y la contraseña del usuario.

Hay un botón "Conectar", que hay que pulsar para establecer la conexión al servidor y a la base de datos. Al conectarse, se ejecuta una consulta inicial que rellena el datagrid con los datos recuperados.

Luego hay un campo de texto, donde se ingresará un nombre o una parte para filtrar los registros de la tabla. Hay una etiqueta donde se da el ejemplo. El ADODC se ve en modo diseño, pero en tiempo de ejecución está oculto por defecto, se puede cambiar, tal como lo hice en el ejemplo.

En esta imagen se muestra el formulario, cuando se pulsa el botón "Conectar" con los parámetros correctos, se listan los registros de la tabla employee.



Y ésta, muestra cuando se ha hecho una consulta filtrando por la palabra "an", se muestran solo los registros que contienen dentro del nombre dicha palabra.



El siguiente es el código del botón "Conectar"

Private Sub cmdConectar_Click()

Dim CadenaConexion As String

CadenaConexion = "Provider=SQLOLEDB.1;Persist Security Info=False;User ID=" + txtUsuario.Text + ";Password= " + txtPassword.Text + ";Initial Catalog=" + txtBaseDatos.Text + ";Data Source=" + txtServidor.Text


With adoEjemplo

.ConnectionString = CadenaConexion

.CommandType = adCmdText

.RecordSource = "SELECT * FROM employee"

.Refresh

End With


With DataGrid1

Set .DataSource = adoEjemplo.Recordset

.Refresh

End With


cmdConectar.Enabled = False


End Sub




Y el siguiente es el código del botón "Buscar":

Private Sub cmdBuscar_Click()

Dim Consulta As String

Consulta = "Select * from employee where fname like '%" + txtConsulta.Text + "%'"


With adoEjemplo

.RecordSource = Consulta

.Refresh

End With


With DataGrid1

Set .DataSource = adoEjemplo.Recordset

.Refresh

End With


End Sub


Conclusión

Como se ve el código no es muy complicado, y es muy similar a lo que se usaría en consultar una base de datos Access, claro que es un ejemplo, y le falta mucho para ser considerado en producción, como control de errores, y otros controles de seguridad. Además, utilizar ADODC en una solución profesional, no es recomendada, como dice la propia Microsoft, es útil para prototipos, no para una solución real.

Descarga desde aquí el código completo.

ACTUALIZADO: Olvidé indicar que la base de datos de ejemplo era la Pubs que viene por defecto con el Sql Server. Si ya la borraron o no la tienen la pueden descargar de aquí.

Espero sea de ayuda para el lector, y también para otros.

Carlos Mayanga

Mis otros blogs:
PCT: Programación y Tecnología
Sistémico en Apuros
Ciudad de Chiclayo: Tienes que conocerla

9 peligros de seguridad en Sql Server

En SearchSqlServer.com dan una lista con los 9 peligros de seguridad más comunes en el trabajo de un administrador de bases de datos:

  1. Ejecutar aplicaciones con privilegios de administrador y dejar al front-end controlar la seguridad del la base de datos.
  2. Los administradores de bases de datos usan cuentas de nivel de administrador para las tareas diarias que no requieren tales privilegios.
  3. Multiples administradores tienen en sus manos los mismos sistemas.
  4. Se comparten las cuentas de administrador de Windows para manejar la base de datos.
  5. No se usan procedimientos almacenados donde son posibles.
  6. No se crean vistas de la base de datos basadas en permisos de usuarios o grupos.
  7. Los registros de auditoría no son revisados.
  8. Multiples administradores para la administración del almacenamiento y copia de seguridad de la base de datos.
  9. Nula o casi inexistente clasificación para ubicar a cada base de datos sobre el mismo nivel de importancia.
Leer el artículo original.

Documentar una base de datos

Para documentar una base de datos, hay que hacerse las siguientes preguntas, y sobre las respuestas se va redactando la documentación, hay que recordar que la documentación se hace mientras se va diseñando la base de datos, si uno olvida de documentar algo, le harás la vida dificil a quien vaya a trabajar contigo, o lo que es peor, a tí mismo.

¿Por qué una tabla en particular es creada?

¿Qué es lo necesario de una columna en particular?

¿Para que usamos el procedimiento almacenado XYZ?

¿Que ha sido efectuado cuando un procedimiento ha sido ejecutado?

Hay muchas herramientas automtizadas para realizar la documentación de una base de datos, especifícamente para Sql Server hay decenas, casi todas de pago, lo más sencillo es utilizar Word o un procesador de textos, para ir documentando la base de datos.

Caso raro de Vistas en Subconsultas

Esto es un caso raro cuando se utilizan vistas. Generalmente se usan las vistas para disminuir la complejidad de las consultas. Y aveces se cambian los nombres de las tablas base que se usan con el mismo proposito.

Veamos que es lo raro. Si tenemos una vista, como la siguiente:

CREATE VIEW dbo.view_ajustes
AS
SELECT
dbo.Puntosventa.nombre AS PuntoVenta, dbo.productos.nombre AS ProductoVenta, dbo.ajustes.preciounitario AS Precio, dbo.ajustes.cantidad
FROM PuntosVenta inner join Productos on PuntosVenta.IdPuntoVenta = Productos.IdPuntoVenta inner join ajustes on productos.idproducto=ajustes.idproducto


Si se quiere realizar una consulta a esa vista:

select puntoventa,productoventa,preciounitario,cantidad
from view_ajustes


Se ejecuta sin error, dando como resultado las filas deseadas. Ahora utilizaremos la vista en una subconsulta.

select *
from puntosventa
where nombre in (select nombre from view_ajustes)


Esta consulta se ejecutará sin errores. Pero chequeenla. En la subconsulta se está utilizando la columna 'nombre' que no existe en la vista view_ajustes y no el campo 'puntoventa'. Aún así no hay errores y Sql Server puede "descifrar" a traves de la vista el nombre de la columna en la tabla base. Pues la columna 'nombre' si existe en la tabla base puntosventa.

Es más como en la misma vista se utilizan dos columnas con el mismo identificador 'nombre' de dos tablas diferentes, la anterior consulta se puede modificar para consultar la tabla productos, sin errores también.

select *
from productos
where nombre in (select nombre from view_ajustes)


Conclusión: Debe ser una "característica" en Sql Server 2000 (también pasa si prueban en Sql Server 2005), mediante la cual en una subconsulta que utilizan vistas, no importa utilizar el identificador utilizado en la vista o el identificador de la tabla base.

Fuente:
Sql Server Central.