diciembre 11, 2006

Check box en GridView para procesar renglones seleccionados

Recientemente tuve la necesidad de poner un ccheck box en cada una de las filas de un control GridView para que poder seleccionar a un número determinado de ellas y asi poder procesarlas.




1. Agregar el control check box al GridView como parte de sus columnas:



2. Recorrer a todos los renglones del GridView para identificar cuales están seleccionados.

'Obtener el total de renglones para saber cunado parar durante la iteración.
Dim intRows As Int16 = Me.GridViewEdoCta.Rows.Count

For i = 0 To Me.GridViewEdoCta.Rows.Count - 1
'En la posición 13 es en donde se encuentra el control Check.
If CType(Me.GridViewEdoCta.Rows(i).Cells(13).Controls(1), CheckBox).Checked Then
CargoxContrato = Me.GridViewEdoCta.Rows(i).Cells(0).Text
End If
Next

Inserciones, Actulizaciones y Borrados masivo de registros

En el siguiente ejemplo se expone como hacer Deletes y Updates masivamente con el uso de XML, sólo es necesario pasar el árbol XML al store procedure para leerlo y especificarlo en las intrucciones delete y update. La´página web referencia es:

http://support.microsoft.com/kb/316244/es

Cadena xml válida que recibe el sp:


CREATE PROCEDURE sps_CancelaCargosXContratoTelXML
@xmlCargosxContrato varchar(8000) AS

DECLARE @idoc int --xmlDoc

--Ejecutar el sp que carga en memoria el docuemnto XML.
EXEC sp_xml_preparedocument @idoc output, @xmlCargosxContrato

--Comienza la transacción
BEGIN TRANSACTION
--Actualizar el Status de los cargos a Cancelado.

UPDATE Tel_CargosxContrato SET Tel_CargosxContrato.Status = 'CANCELADO'FROM OPENXML (@idoc, '/CargosxContrato/Concepto')
WITH (CargoUid varchar(11)) Tel_CargosxContratoXML
WHERE Tel_CargosxContrato.Uid = Tel_CargosxContratoXML.CargoUid

--Verificar si hubo errores saltar al bloque manejador.

IF @@Error != 0
GOTO ERROR_HANDLER
--Eliminar cargos de la tabla TEL_Cobranza

Delete Tel_cobranza
FROM OPENXML (@idoc, '/CargosxContrato/Concepto')
WITH (CargoUid varchar(11)) CobranzaXMLWHERE Tel_Cobranza.Uid = CobranzaXML.CargoUid

--Verificar si hubo errores saltar al bloque manejador.
IF @@Error != 0
BEGIN
GOTO ERROR_HANDLE

--Finalizar la Transacción pues todo salió bien.
COMMIT TRANSACTION
SET NOCOUNT OFF
--Descargar documento XML de la memoria.
EXEC sp_xml_removedocument @idoc
RETURN 0

--Manejador de Error.
ERROR_HANDLER:
ROLLBACK TRANSACTION--Descargar documento XML de la memoria.EXEC sp_xml_removedocument @idoc
SET NOCOUNT OFF
RETURN 0
GO

Ocultar columnas con DataBind en un GridView

Es muy comun el poblar un control GridView con datos de una Base de Datos y ocultar columnas que no es recomendable que se muestran a los usuarios, pero en el GridView al poner la propiedad visible= False de una columna a ocultar y luego tratar de recuperar el valor de esta celda el valor es cadena vacía, para que esto no courra se debe implementar el siguiente evento manejado del GridView y aquí poner las columnas que se desea ocultar.

'Ocultar columnas del GridView que no son necesarias para el usuario en la vista.
Public Sub myGrid_OnRowCreated(ByVal sender As Object, ByVal e As Web.UI.WebControls.GridViewRowEventArgs) Handles GridViewEdoCta.RowCreated
e.Row.Cells(0).Visible = False 'Uid cobranza
e.Row.Cells(1).Visible = False 'MovimientoUid
End Sub

De esta forma si es posible recuperar su valor.
'Recuperar el valor de la celda, aunque este oculta.
Dim strClave as String = Me.GridViewEdoCta.Rows(1).Cells(0).Text

Imprimir directamente con ASP.NET


1. En el evento Load cargo la lista de impresoras disponibles localemente.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
Me.DropDownListImpresoras.DataSource = PrinterSettings.InstalledPrinters()
Me.DropDownListImpresoras.DataBind()
Me.DropDownListImpresoras.SelectedIndex = 0
End If
End Sub

2. Al hacer clic en el botón imprimir
Protected Sub ButtonImprimir_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ButtonImprimir.Click
'Create an instance of PrintDocument
Dim printdoc As New System.Drawing.Printing.PrintDocument()
' Set the printer name
printdoc.PrinterSettings.PrinterName = Me.DropDownListImpresoras.Text
' Handle printing
AddHandler printdoc.PrintPage, AddressOf Me.printdoc_PrintPage
' Print!
printdoc.Print()
End Sub

3. Evento manejado al imprimir que es en donde se especifica lo que se desea imprimir.

Private Sub printdoc_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
'Definición de la fte a utilizar.
Dim printFont As System.Drawing.Font = New System.Drawing.Font("Courier New", 12)

' Dibujar el nombre escrito y que se desea imprimir directamente.
e.Graphics.DrawString(Me.TextBox1.Text, printFont, System.Drawing.Brushes.Black, New System.Drawing.PointF(10.0F, 50.0F))
End Sub

noviembre 08, 2006

Script para Activar/Desactivar Constraints en SQL Server

Muchas veces es necesario deshabilitar la integridad referencial o ciertos constraints establecidos en una base de datos SQL Server y este script que encontré en "http://www.melkorcete.com/index.php?c=17" es muy útil para llevar acabo esta tarea.


/*
Script para Activar y Desactivar todos los constraints de una
Base de Datos (CK, FK, PK, DK).

Sólo se especiifca 1 para activar o 0 para desactivar a la variable @p_activar
*/

USE Facturacion

DECLARE @p_activar BIT
SET @p_activar = 1 --Para Activar = 1, Desactivar = 0

Declare @v_retorno int

Begin
Set NoCount Off

-- Almacena la Orden
declare @orden varchar(100)
-- Almacena la Tabla
declare @tabla varchar(100)
-- Almacena el numero de Operacion Realizada
declare @contador int
-- Variables para mensaje
declare @no varchar(2)
declare @des varchar(4)

-- Para la construccion de mensajes se da un valor
-- dependiendo del parametro @p_activar
if @p_activar = 1
begin
set @no = null
set @des = 'A'
end
else
begin
set @no = 'NO'
set @des = 'Desa'
end

-- Cursor para recorrer una a una las Constraints
declare CURSORITO cursor for
SELECT 'ALTER TABLE ' + QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) + ' ' + IsNull(@no,'') + 'CHECK CONSTRAINT ALL',TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE
OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)), 'IsMSShipped') = 0
AND TABLE_TYPE = 'BASE TABLE'

-- Inicializacion de Variables
set @orden = ''
set @tabla = ''
set @contador = 0

-- Mensaje de entrada
print ' '
print '####################################################'

if @no = 'NO'
print '### DESACTIVADO DE CONSTRAINTS ###'
else
print '### ACTIVADO DE CONSTRAINTS ###'

print '####################################################'
print '### '

-- Iniciamos el Cursor y lo recorremos
OPEN CURSORITO
fetch next from CURSORITO
into @orden,@tabla
while @@fetch_status = 0
begin
-- Contador ++
set @contador = @contador + 1
-- Ejecutamos la Orden
exec(@orden)
-- Crear mensaje de salida
print '### ' + convert(varchar,@contador) + ' - ' + convert(varchar,@des) + 'ctivado de ' + convert(varchar,@tabla) + ' completado.'
-- Siguiente Vuelta
fetch next from CURSORITO into @orden, @tabla
end
-- cerramos el cursor
close CURSORITO
deallocate CURSORITO

-- Mensaje de Fin
print '### '
print '####################################################'

if @@error = 0
print '### FINALIZADO CORRECTAMENTE ###'
else
print '### FINALIZADO CON ERRORES ###'

print '####################################################'

Select @v_retorno = @@error
End

octubre 16, 2006

Un control Web ASP. net que expone un dialogo de espera

Este en un control asp net que funciona para la versión 1.1 y 2 y que es muy útil para mostrar al usuario cuando éste debe esperar a que se procese la página.

El link es:


http://busyboxdotnet.qsh.eu/



Revisen el demo. Considero que es un control free muy útil.

octubre 13, 2006

Encriptado de información del ViewState ASP 2.0

Para reducir el riesgo que alguien intercepte la información almacenada en el ViewState, es posible cifrar dicha información.

Los valores aceptados de la propiedad ViewStateEncryptionMode son:

Always: La información del ViewState siempre es encriptada. Si la aplicación maneja información sensible de manera constante seria conveniente utilizar este valor.

Auto: La información es encriptada si un control lo solicita. Este es el valor por defecto de la propiedad.

Never: La información nunca es encriptada, aún si un control lo solicita. Úselo bajo su propia responsabilidad...

Para establecer el valor a nivel de aplicación empleamos el atributo ViewStateEncryptionMode de la sección pages en el web.config:

pages viewStateEncryptionMode="Always"


O bien por medio del atributo homónimo de la directiva @Page, para establecer el valor en una página en particular:

@Page ViewStateEncryptionMode="Always"

También se puede establecer el valor de manera dinámica a través de la propiedad ViewStateEncryptionMode del objeto Page:

Page.ViewStateEncryptionMode = ViewStateEncryptionMode.Auto

Así pues, utilizando el valor por defecto (Auto) de la propiedad ViewStateEncryptionMode, si se requiere que la información del ViewState sea encriptada, se debe llamar al método RegisterRequiresViewStateEncryption del objeto Page:

If () Then
Page.RegisterRequiresViewStateEncryption()
End If

Formatear (Identación) las instrucciones SQL

Navegando por Internet encontré este formateador de instrucciones SQL en línea, me gusto mucho pues resulta muy útil para cuando hacemos scripts, stores procedures o disparadores.


Este es el link de referencia:

http://www.wangz.net/cgi-bin/pp/gsqlparser/sqlpp/sqlformat.tpl

octubre 05, 2006

EXISTS vs. COUNT(*) en SQL Server

Es muy común que querramos saber la existencia de datos en determinada tabla de una base de datos y para ello utilizamos EXISTS o COUNT(*), pero qué es más eficiente?

Pues en un artículo que muestra como es más eficiente utilizar EXISTS.


IF EXISTS(SELECT * FROM OrderDetails
WHERE orderid = 10248)
PRINT 'yes'
ELSE
PRINT 'no'

Este es el link de referencia:

http://www.sqlmag.com/Article/ArticleID/38039/sql_server_38039.html

Manual de Diseño e Implementación de Base de Datos

Este es el link al manual en línea:


http://www.sqlmax.com/centro/programa.asp

Cargar DataTable con DataReader NET 2005

Ahora en VB.NET 2005 el objeto DataTable puede cargarse via IDataReader (por ejemplo un SqlDataReader) sin necesidad de un objeto SQLDataAdapter. El DataTable tiene un método Load que acepta como argumento un obj que implemente IDataReader.

El siguiente ejemplo pobla un DataView con un DataTable que a su vez es poblado con un SQLDataReader.


----------------Código Fte----------------------------------------------
Imports System.Data.SqlClient

Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Me.DataGridView1.DataSource = llenaDataTableConRS()

End Sub


'Función que ejecuta el reader y carga los resultados en una DataTable.
Private Function llenaDataTableConRS() As DataTable
Dim con As New SqlConnection(strConn)

Dim datatable1 As New DataTable
Dim dr As SqlDataReader
Try
Dim cmd As New SqlCommand("Select * From Employees", con)
con.Open()
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
'Aqui es donde se carga el Recordset al DataTable.
datatable1.Load(dr)

Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
con.Close()
End Try

Return datatable1
End Function
End Class

Guardar la hora como un entero en SQL Server.

Una opción de guardar la hora es como un valor entero, por ejemplo si son las 11:20 entonces el valor sería guardado como 1120. Sólo es necesario multiplicar por 100.

En el ejemplo se crea una tabla temporal.
Se le agrega un registos con la hora como un entero.
Se consulta el valor guardado.
Se borra la tabla temporal.

--Creación de tabla termporal.
SET NOCOUNT ON
CREATE TABLE #foo
(
tm SMALLINT
)
go

--Insertar la hora y minutos actuales del equipo
INSERT #foo VALUES
(
-- e.g. 1527 = 3:27 PM / 15:27
100 * DATEPART(HOUR, GETDATE())
+ DATEPART(MINUTE,GETDATE())
)

go

--Imprimir la hora y minutos guardados
SELECT tm FROM #foo
go

--Borrar la tabla temporal
DROP TABLE #foo
go
----------------------------------------------------

Verifica si existe tabla en una BD en SQL Server

--Verifica si existe una tabla temporal.
IF OBJECT_ID('tempdb..#AnyTable') IS NOT NULL
PRINT 'EXISTE'
ELSE
PRINT 'NO EXISTE'
go


--Verifica si existe tabla en determinda Base de datos.
IF OBJECT_ID('Northwind..Categories') IS NOT NULL
PRINT 'EXISTE'
ELSE
PRINT 'NO EXISTE'
go

Función SQL Server verifica existe columna en tabla

--------------------Código de la Función-----------------------------
CREATE FUNCTION ColumnAlreadyExists(@TableName NVARCHAR(128),@ColumnName NVARCHAR(128))
RETURNS INTEGER--Returns 0 if column does not exist. Returns 1 if column exists.
AS
BEGIN
--See if the Table already contains the column.
IF EXISTS
(SELECT * FROM SysObjects O INNER JOIN SysColumns C ON O.ID=C.ID
WHERE ObjectProperty(O.ID,'IsUserTable')=1
AND O.Name=@TableName
AND C.Name=@ColumnName)
RETURN 1
--Table does not contain the column.
RETURN 0
END
GO

----------------------Usar la función-------------------------IF .dbo.ColumnAlreadyExists('CLIENTE','IdCte')=1
print 'Existe la columna IdCte en la tabla.'
Else
print 'No existe la columna IdCte en la tabla.'
--------------------------------------------------------------

agosto 04, 2006

MARS (Multiple Active Result Sets)

Sobre algo de lo nuevo en NET 2.0 y SQL Server 2005 está el concepto llamado: Multiple Active Result Sets y que la idea es poder trabajar con la misma conexión para dar realizar más de una operación en la base de datos, por ejemplo leer un conjunto de resultados de un datareader y que para cada registro obtenido hacer un insert. Para realizar está operación con SQL Server 2000 es necesario utilizar dos objetos conexión, pero ahora con MARS (Multiple Active Result Sets es posible realizar esto con una sóla conexión, sólo es necesario especificar esta funcionalidad en la cadena de conexión.



connectionString = "Data Source=(local);Integrated Security=SSPI;" & _
"Initial Catalog=AdventureWorks; MultipleActiveResultSets=True"

Using awConnection As New SqlConnection(connectionString)

Este es un link con más información al respecto:

http://msdn2.microsoft.com/en-us/library/yf1a7f4f.aspx

Tipo Nullables en net 2.0

Hace unos días mi amigo Orlando hizo un procedimiento en visual basic net que leía un datareader, extraía los valores y éstos los pasaba a una función que los recibía para hacer un insert. Él me preguntaba como podia pasar un valor nulo como parámetro a una función y yo le conteste que eso no era posible porque lo que lo que él estaba pasando eran valores a variables escalares y no objetos.

Él necesitaba pasar un valor nulo a su función cuando el datareader que el leía contenía un nulo. Al dia siguiente encontré el concepto de valores nulables soportados por el framework 2.0 y esta es la forma en que se pueden utilizar.

'Asignar un valor nulo al tipo escalar
Dim booleanoNulo as Nullable(Of Boolean) = Nothing
Dim IntegerNulo As Nullable(Of Integer) = 34
'Llamar al método.
valor(booleanoNulo , IntegerNulo )

'Se puede usar la propiedad HasValue de los tipos nullables para preguntar si la variable tiene o no un valor asignado. A continuación se muestra una función que recibe tipos de datos escalares con valores nulos.

Private Sub valor(ByVal booleanoNulo As Nullable(Of Boolean), ByVal IntegerNulo As Nullable(Of Integer))

If booleanoNulo.HasValue() Then
'Asignar Valor.
MessageBox.Show(booleanoNulo.Value)
Else
MessageBox.Show("No existe valor x asignar entonces insertar System.DbNull.Value.")
End If

End sub

Obtener fecha y hora de un datetime en SQL Server

Muchas veces es neesario extraer sólo la fecha u hora a un valor correspondiente a un tipo Datetime en SQL Server.

Aquí están algunas de las formas de obtenerlo:

SELECT CONVERT(CHAR(10), FechaAlta, 103) AS SoloFecha
FROM Tabla
--103 es el formato corto de dd/mm/aaaa

SELECT dateonly = CONVERT(CHAR(8),FechaHora1,112) FROM TABLA1
SELECT timeonly = CONVERT(CHAR(8),FechaHora1,8) FROM TABLA1

junio 06, 2006

Conocer la disponibilidad de acceso a la red con NET 2.0

Algo que recientemente leí sobre lo nuevo en el espacio nombres en NET 2.0 fue una clase que nos permite detectar si el acceso a la red está disponible. A mi gusto mucho porque anteriormente yo conocía esto hasta que atrapaba la excepción hasta el momento en que se realizaba una operación con el manejador de base de datos en red. Existen dos formas y cualquiera de ellas regresa un valor boleano.

--Forma 2
MessageBox.Show("Está disponible la conexión: " & System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())


--Forma 1
MessageBox.Show("Está disponible la conexión: " & My.Computer.Network.IsAvailable)

Otra funcionalidad nueva es poder hacer un ping:

My.Computer.Network.Ping("Server")
En donde "Server" puede ser el nombre del servidor o su IP

mayo 29, 2006

Los cuatro puntos de la cardinalidad de la relación durante el diseño de la BD.

Hay una restricción importante que se declara gráficamente en las relaciones en el diagrama Entidad-Relación y se llama la cardinalidad, la cual representa qué tantos de una cosa se relacionan con otra. La cardinalidad de la relación es particularmente importante debido a que forma la base de muchas decisiones de diseño. La cardinalidad se expresa con un valor para un mínimo y para un máximo. El valor mínimo describe si la relación es opcional o requerida. El valor máximo describe si la relación es singular o plural. Debido a que las relaciones se indican en ambas direcciones entre las dos entidades, la cardinalidad mínima y máxima también debe ser indicada en ambas direcciones. Esto significa que para cada relación del modelo se requieren cuatro puntos de cardinalidad para expresar adecuadamente la naturaleza de la relación (mínimo y máximo en ambas direcciones).

A continuación veremos mediante un ejemplo el uso de las cuatro preguntas de la cardinalidad de la relación. Vamos a suponer que estamos elaborando una aplicación de facturación, para lo cuál vamos tomar las entidades de este modelo. Decimos que un Cliente compra Productos, entonces existe una relación entre ambas entidades.









Ahora identificamos la cardinalidad de la relación, para ello nos plantemos las siguientes cuatro preguntas –preguntas de la cardinalidad de la relación-

1. Debe un CLIENTE comprar un PRODUCTO? No. Para ser cliente efectivamente alguna vez nos compró, pero después no, así que ya es CLIENTE, pero no necesariamente debe comprarnos productos, después de la primera vez.

2. Puede un CLIENTE comprarnos más de un PRODUCTO? Si. Esto depende de la naturaleza de operación de la organización, pero lo común es que al levantar un pedido a un CLIENTE este puede solicitarnos a más de un PRODUCTO.

3. Debe un PRODUCTO ser comprador por un CLIENTE? No. Porque no podemos forzar a que un PRODUCTO sea comprador por un CLIENTE.

4. Puede un PRODUCTO ser comprador por más de un CLIENTE? Si. Esto es viendo desde el concepto de PRODUCTO y no como una pieza fisica.

Podemos observar que las dos primeras preguntas van enfocadas del CLIENTE al PRODUCTO y las otras dos preguntas del PRODUCTO al CLIENTE.

La pregunta 1 está diseñada para obtener la cardinalidad mínima.
La pregunta 2 está diseñada para determinar si la misma instancia de la entidad A puede participar en relaciones con varias instancias de la entidad B al mismo tiempo.

Cuando quedan determinadas las respuestas a las preguntas 1 y 2, el analista puede poner la cardinalidad mínima y máxima en el diagrama para expresar las reglas de negocio. La notación de la cardinalidad mínima es un cero que significa opcional, o un uno que significa requerida. La notación para la cardinalidad máxima es un uno, que significa solamente uno o un par de patas de gallo significa muchos.









La cardinalidad mínima y máxima debe ser expresada en ambas direcciones para definir adecuadamente la regla de negocio.



Así es como se ve nuestro modelo después de aplicar las cuatro preguntas de cardinalidad.



Pero como sabemos que las relaciones muchos a muchos no se soportan en un RDBMS, entonces nace debe crearse una nueva entidad asociativa que resuelva este tipo de cardinalidad y ésta es FACTURA.


Después de aplicar las cuatros preguntas de cardinalidad, nuestro modelo queda así:



Podemos observar que ahora ha aparecido otra relación muchos a muchos y que es necesario resolver, yo lo llamaré DETALLE_FACTURA. En la siguiente figura se expone el cómo se vería nuestro modelo Entidad-Relación terminado.





Una nota importante a la hora de aplicar las cuatro preguntas de la cardinalidad es el verbo que se nombra entre la relación de ambas entidades, por ejemplo el cliente compra, el producto se incluye, etc.

mayo 28, 2006

Cómo funciona y por qué usar AJAX?

No hace mucho tiempo me enteré de una nueva tecnología que aprovecha a XML y javascript para hacer a nuestras aplicaciones WEB más responsivas y en la web encontré lo que a continuación expreso.

El Web y Ajax

Problema: La recarga de una vista o página anteriormente cargada cuando lo único que se va a modificar entre request y request son sólo datos. La vista sigue siendo la misma. Es decir de evita el rearmado de la vista con los nuevos datos y el viaje de la misma desde el servidor.

Causas: La coomunicación entres el cliente y el servidor es a través de request -peticiones- Y se deja que le servidor genere una nueva vista, pero con los nuevos datos cargados para que el cliente los visualice, cuando en realidad la misma sigue igual, sólo modifica sus datos.

Solución: Separar los datos de la vista. Mediante el uso de un pequeño controlador invoker del lado del cliente dentro de la vista, que administre los datos. Mediante el uso del modelo de objetos del navegador y scripting del lado del cliente se realiza la carga y manejo de datos sobre la vista anteriormente solicitada sin necesidad de realizar un request cuando es posible con los datos actuales. Y al momento de necesitar una acción del servidor para obtener más datos, se realiza la misma evitando la recarga de la vista que continuo siendo la misma.

Ventajas:
1) Solución simple de implementar.
2) Permite obtener datos bajo demanda y luego visualizarlos sin recargar las vistas.
3) Las vistas no se ven afectadas en cuanto a tamaño y éstas pueden ser cacheadas por el navegador ya que las mismas no expirarían continuamente ya que sus datos son manejados independientemente de la presentación.
4) Las vistas no son reescritas por el servidor por lo que separa más la vista en si de los datos, permitiendo un mejor manejo por los diseñadores.

Desventajas:
1) Utiliza frames ocultos.
2) Utiliza más scriptting del lado del cliente

Resumen: Con Ajax se evita la recarga de las vistas cunado no es necesario cambiarla, sino que busca los datos y carga a los mismo en la vista.

Identificación de Reglas de Negocio

Durante la etapa de análisis la toma de requierimientos es de extrema importancia para lograr el éxito del proyecto y no llegar la final con "una solución elegante a un problema equivocado" y como parte de esta etapa está la identificación de las fomosas "REGLAS DE NEGOCIO".


Qué son las Reglas de Negocio? En el libro "UML y Patrones" de Craig Larman dice:
"Las reglas del dominio dictan en modo en el que podrán operar un dominio o negocio. No son requisitos de ninguna aplicación, aunque, a menudo, los requisitos de una apliación se ven afectados por las reglas del dominio. Las políticas de la compañía, leyes físicas y leyes gubernamentales, son reglas de dominio típicas.

Se demoninan comunmente reglas del negocio, que son el típico más común, pero ese término está limitado, ya que existen aplicaciones de software que no son de gestión de un negocio, como la simulación del clima o la logística militar. Una simulación del clima incluye reglas del dominio, relacionadas con las leyes y relaciones físicas que afectan a los requisitos de la aplicación.

Avertencia: Las reglas no son requisitos de la aplicación. No registre las caracteristicas del sistema como reglas. Las reglas describen las restricciones y comportamientos del modo de trabajar del dominio, no de la aplicación"

Como ven los parrafos anteriores son muy interesantes, pero a continuación aquí hat algo más que encontré en la web sobre las reglas de negocio:

1. Criterios para identificar reglas de negocio o del dominio.

- Condiciones que se deben satisfacer para considerar válidos los datos. Por ejemplo sólo se puede enviar la mercancía hasta que el cliente haya pagado.

- Condiciones que deben ser evitadas.
Por ejemplo que el inventario de cierto producto llegue a cero.

- Secuencias en las que los eventos deben de ocurrir.
Se debe determinar que hacer cuando el inventario llega a cero o cuando un pago para una orden es recibido.

2. Métodos para implementar reglas de negocio.

- Directamente en la base de datos.
DataTypes, Default Values, Rules, Keys y Triggers. (En una palabra constraints de Base de Datos).

- Programación dentro o fuera de la base de datos.
Store Procedures, objetos de negocio, validación directamente en la capa del cliente.

Clasificación de los reportes durante el desarrollo de sistemas.

Los reportes son las salidas de la información que las organizaciones utilizan para la toma de desiciones o para realizar tareas o procesos de negocio y como desarrolladores estamos comprometidos a crear a la hora de implementar una aplicación.

Cuando trabajé en en un proyecto y que participé desde la fase de toma de requerimientos los usuarios nos empapelaron de solictudes de reportes que según ellos eran necesarios que el sistema les dejará imprimir, yo le comenté a mi jefe sobre está situación y le mencioné que desde mi punta de vista consideraba que muchos de ellos eran imprácticos e innecesarios, entonces él los revisó y aquí es donde él me explicó: existen dos tipo de reportes que se implementan en el desarrollo de sistema: los reportes soporte a la operación y los reportes soporte a la toma de decisiones y que cuando para una aplicación no se ha hecho una adecuada toma de requerimientos, entonces lo que no puede exponer el programa el desarrollador lo hace con reporte(s). Y cuáles son los reportes soporte a la operación: son los reportes escenciales y que necesariamente se tienen que implementar pues la solución no tienen razón de ser si estos no son implementados, por ejemplo la impresión de una factura en un sistema de facturación, la impresión de una receta médica en un sistema de consultas médicas, la impresión de un cheque en un RP, el ticket en un sistema de punto de ventas, etc. Existen muchos de estos casos de reportes. Luego tenemos los reportes soporte a la toma de desiciones y cuyo objetivo es mostrar concentrados de información o información resumen cuyo objetivo es permitirle a los usuarios o empleados de la organización tomar de desiciones, por ejemplo un reporte que concentré las ventas del año pasado agrupadas por mes, un reporte de inventarios por categoria de producto, etc. Y para la demás información no se requiere un reporte pues está en pantalla, de ahí lo que me decia mi exjefe Ing. Arnulfo González si haz hecho una buena toma de requerimientos el sistema lo contendrá y no tendrás que elaborar un reportes excepto para los casos de reportes soporte a la operación o a la toma de decisiones. Así que desarrolladores cuando el usuario les pida reportes, ustedes identifiquen a que tipo de estás dos clasificaciones pertenece y lo que les sobre será información que estará presente en todo momento en pantalla y que no es necesario su impresión -como los de soporte a la operación cuya impresión es 100% necesaria.

Qué lenguaje de programación utilizar: VB.NET o C#

El pasado 26 de mayo de 2006 se realizó la tercera reunión de la comunidad .NET del D.F, en el auditorio "Carlos Graef" de la facultad de Ciencias de la UNAM. Se expusieron temas muy intersantes y por ahí alguien le preguntó a Octavio Telis sobre que lenguaje era mejor si VB.NET o C# y creo que su pregunta fue muy certera, pues el mencionó que en las primeras versiones había cosas que hacia C# y que no hacia VB.NET -cómo los tipos sin signo, etc- pero que esas diferencias ahora ya no existian entre ambos lenguajes, pero déspues mencionó lo que yo creo es lo más importante: "El objetivo del lenguaje es lo que está debajo de él: el Framework". Yo considero que está fue una respuesta muy intersante y cierta. A continuación pongo unos diagramitas que por ahí encontré en la web y que consideron que son muy importantes y que hacen alusión a este post.

mayo 23, 2006

El manejo de fechas en SQL Server

En algún momento hice una pequeña aplicación que seleccionaba n número de renglones de una tabla en SQL Server 2000, pero al ejecutarla ésta seleccionaba un número de registros menor a los que yo espera estuvieran en ese rango de fechas. Lo primero que yo pensé fue en la configuración regional del equipo y que éste tenia un formato de fecha diferente al que yo quería "dd-mm-aaaa" y que cómo ustes saben nuestros primos los gringos usan "mm-dd-aaaa", y ooh! sorpresa estaba bien la configuración regional, entonces le pregunte a un amigo y me dijo que era el lenguaje que tenia definido el SQL Server y que incluso esto era independiente del lenguaje de mi SQL Server puesto que es un valor configurable.

Y aquí encontré esta página que expone como utilizar las fechas independientemente del lenguaje con el que esté configurado SQL Server.



http://www.microsoft.com/spanish/msdn/comunidad/mtj.net/voices/art157.asp

Uso de XML con SQL Server 2000 para operaciones que requieren transacciones con n registros

En algún momento que leía un libro de SQL Server 2000 me sorprendió encontrar una forma de utilizar XML con SQL Server 2000 para poder insertar n registros en una sola operación -también llamada transacción-. Para poder lograr esto SQL Server 2000 cuenta con un procedimiento almacenado llamado: "sp_xml_preparedocument" que es el encargado de leer la cadena con formato XML y cargarla en la memoria para poder recorrerla.

A continuación expongo un ejemplo del caso de la inserción de un objeto Factura en la Base de Datos utilizando XML. Como todos sabemos una factura se compone de dos conceptos: un encabezado y un detalle, el encabezado es el que expone datos del cliente, la fecha y otros, estos datos conforman un registro o renglón en la Base da datos y se inserta en una tabla llamada Factura. El siguiente concepto u apartado que conforman a una factura es el Detalle, éste contiene a todos los registros o renglones de los conceptos que se están facturando al cliente y que pueden ser uno o más (ver figura del modelo Entidad/Relación) y aquí es en donde XML viene a facilitarnos la vida para poder insertar los dos objetos -el encabezado y el detalle- en una sola operación.











La solución se expone como un store procedure que recibe los datos que componen al encabezado y la cadena XML que compone a los del detalle, así que la única condición para que sp_xml_preparedocument pueda leer la cadena XML es que ésta sea válida.

Espero que les sea de mucha utilidad, porque casi que yo siempre la utilizó en los proyectos que desarrollo, pues el patrón maestro-detalle por lo regular siempre está presente de alguna forma en todo proyecto.

----------------------------------------------------------------------------
/*
Este procedimiento almancenado inserta un Encabezado-Detalle de una Factura.
El Detalle se pasa como una cadena XML con la siguiente estructura:

*/

CREATE PROCEDURE dbo.spInsertXMLEncDetFactura
(
@IdCte int,
@FechaFactura datetime,
@IVA numeric(8,2),
@SubTotal numeric(8,2),
@xmlDetFactura varchar(8000)--o tipo Text -Cadena XML con el detalle de la factura.
)
AS

DECLARE @idoc int --xmlDoc
DECLARE @IdFactura int --Nueva Folio Factura

--Ejecutar el sp que carga en memoria el docuemnto XML.
EXEC sp_xml_preparedocument @idoc output, @xmlDetFactura

--SET NOCOUNT ON
DECLARE @CurrentError int

--Comienza la transacción
BEGIN TRANSACTION
--Agregar el encabezado de la factura.

INSERT INTO FACTURA
(IdCte, FechaFactura, IVA, SubTotal)
VALUES (@IdCte, @FechaFactura, @IVA, @SubTotal);

--Verificar si hubo errores
SELECT @CurrentError = @@Error
IF @CurrentError != 0
GOTO ERROR_HANDLER


--Obtener el nuevo Identity de la tabla FACTURA.
SELECT @IdFactura = @@IDENTITY

--Agregar conceptos de FACTURA a la tabla DET_FACTURA.
INSERT INTO DET_FACTURA (IdFactura, IdProducto, CantidadProducto, PrecioProductoVta)
SELECT @IdFactura, IdProducto, CantidadProducto, PrecioProductoVta
FROM OPENXML (@idoc, '/DetFactura/Concepto')
WITH DET_FACTURA

--Verificar si hubo errores
SELECT @CurrentError = @@Error
IF @CurrentError != 0
GOTO ERROR_HANDLER


--Finalizar la Transacción
COMMIT TRANSACTION
SET NOCOUNT OFF

--Descargar documento XML de la memoria.
EXEC sp_xml_removedocument @idoc
--Retornar el nuevo No. de Solcitud de Compra.
RETURN @IdFactura

--Manejador de Error.
ERROR_HANDLER:
ROLLBACK TRANSACTION
--Descargar documento XML de la memoria.
EXEC sp_xml_removedocument @idoc
SET NOCOUNT OFF
RETURN 0
GO

mayo 15, 2006

Acceso a tu computadora virtual desde el navegador.

Hace unos días platiqué con mi amigo Alex y me comentó sobre un sitio desde el cual era posible acceder a una comútadora virtual desde el navegador, así que la visité y me sorprendió mucho la interfaz y las ventajas que da tener acceso a ésta. A mi me gusto lo de poder compartir carpetas con otros usuarios registrados. La interfaz es muy parecida a un ambiente gráfico de una distribución de Linux y lo más increíble es que es free. Aquí algunas de las caracteristicas que te ofrece son:

- Acceso a la computadora sólo tienes que escribir en la barra del navegador Computadora.de/usuario desde cualquier máquina conectada a Internet

- Correo.de.- Al registrarte en Computadora.de obtienes automáticamente una cuenta de correo electrónico y una adicional si elegiste un "alias"; ambas con terminación @correo.de. (uusario@@correo.de)

- Calendario.de.- Organízate y no llegues tarde, Calendario.de te avisa de tus citas pendientes.

- Directorio.de.- Almacena la información de toda la gente que conoces dentro de un programa en donde puedes consultarla con rapidez y eficiencia

- DiscoDuro.de.- Obtienes en tu DiscoDuro.de 100MB de espacio. Toda la información de tu computadora virtual, mensajes, documentos, citas y contactos, están disponibles donde quiera que estés. Crea nuevos directorios, sube tus tareas, fotos y accédelos desde cualquier máquina, sin tener que andar cargando diskettes. De necesitar espacio adicional, por favor haz doble clic en el icono de "Comprar espacio en disco duro"

- Mensajero.de.- Comunícate de forma instantánea con todos tus amigos, sin tener que configurar nada

- Programas.de.- Crea y guarda tus documentos con programas de procesador de palabras y hoja de cálculo compatibles y fáciles de usar

- PaginaWeb.de.- En tu DiscoDuro.de se encuentra una carpeta con este nombre donde podrás poner tu página hogar con imágenes, sonidos y lo que desees. Para acceder a tu página sólo tienes que escribir en la barra del navegador PaginaWeb.de/tu_usuario


http://computadora.de/

Script 2 para otorgar permisos de ejecución a sp a un usuario de SQL Server.

Este es otro script que permite otorgar permisos de ejecución a todos los procedimientos almacenados de una base de datos para un usuario en particular.

*****************************SCRIPT*********************************************
--Otorga permisos a todos los stores procedures para un determinado usuario.
--Precondiciones: establecer el nombre de la base de datos de uso y el nombre del usuario al que se desea otorgar los permisos.

Use x
--Nombre de Usuario al que se desea otorgar permiso.
Declare @user varchar(100)
Set @user = 'User1'

--Seleccionar a todos los objetos del tipo store procedure.
declare curse cursor for
SELECT name
FROM sysobjects
WHERE type = 'P' AND category = 0

OPEN CURSE
declare @proc varchar(100)
declare @stmt nvarchar(200)

fetch next from curse into @proc
while @@fetch_status=0
begin
--ejecuta el otorgamiento de permisos.
set @stmt='grant execute on '+@proc+' to ' +@user
exec SP_EXECUTESQL @STMT
print '***El usuario: ' + @user + ' puede ejecutar al store procedure: ' + @proc + '***'
fetch next from curse into @proc
end
--desocupa el cursor.
close curse
deallocate curse
GO
**************************FIN*SCRIPT*********************************************

Script 1 para otorgar permisos de ejecución a sp en SQL Server .

Recientemente yo tenía que otorgar permisos a muchos usuarios a muchos store procedures en SQL Server 2000 y hacerlo manualmente era una tarea tediosa, así que por ahí me encontré algo en internet para poder hacer esto.

Cuando ejecuten este script sólo especifiquen el nombre de la base de datos.
Después de ejecutarlo les aparecerán ciertos mensajes de error y que no afectan para
el objetivo. Este error se da porque en la consulta:

SELECT name FROM master..sysxlogins
WHERE srvid IS NULL AND name <> 'sa'

Se extraen a todos los usuarios en la base de datos y muy probablemente los usuarios
a los que desea otorgar permisos de ejecución a los SP no existen en la base de datos especificada, pero si los otorgará a los que si existen, de esta manera el
motor de SQL Server excluirá automáticamente a estos y lo expresará mediante un mensaje de error.

--*********************************SCRIPT****************************************
--Otorga permisos de ejecución a todos los sp a todos los usuarios de una base de datos.
--Especifique la BD que desea usar para otorgar.

Use NombreBD

--Variables de uso
Declare @login varchar(50), @proc varchar(100), @stmt nvarchar(200)

DECLARE loginBD CURSOR FOR
--Extraer a todos los logins, no importa que no estén en la BD de uso.
SELECT name FROM master..sysxlogins
WHERE srvid IS NULL AND name <> 'sa'

-- Avanzamos un registro y cargamos en las variables los valores encontrados en el primer registro
OPEN loginBD

FETCH NEXT FROM loginBD
--Vaciar el valor obtenido por el curos en una variable.
INTO @login

WHILE @@FETCH_STATUS = 0
BEGIN
Declare curse cursor for
--Obtener a todos los SP de la base de datos actual.
SELECT name
FROM sysobjects
WHERE type = 'P' AND category = 0
OPEN CURSE
fetch next from curse into @proc
while @@fetch_status=0
Begin
--Ejecutar los permisos
set @stmt='grant execute on '+@proc+' to ' +@login
exec SP_EXECUTESQL @STMT
If @@Error<> 0
print ''
Else
print '***El usuario: ' +@login + ' puede ejecutar al store procedure: ' + @proc
fetch next from curse into @proc
end
--Desocupar el cursor
close curse
deallocate curse

-----Siguiente Login
FETCH NEXT FROM loginBD
--Vaciar el siguiente valor obtenido por el curos en una variable.
INTO @login
END

--Desocupar el cursor.
CLOSE loginBD
DEALLOCATE loginBD
GO
--*****************************FIN*SCRIPT****************************************

mayo 10, 2006

Grupos de Noticias de Productos Microsoft.

De vez en cuando entrar a los grupos de discusión de Microsoft suele ser muy bueno porque de acuerdo al tema uno puede ayudar o otras personas o aprender de lo que se expone como pregunta-respuesta.


http://support.microsoft.com/newsgroups/


Despúes de ingresar a la página sólo seleccionen el idioma y un producto para ver las preguntas expuestas.

Tip de performance al usar una conexión de BD a través de un SqlDataAdapter.

Navegando en la web encontré un link que me llevó a un blog muy interesante y ahí en un post encontré información a cerca del manejo del pool de conexiones que hace ADO.NET cuando se utiliza un SqlDataAdapter. Se sabe que al ejecutar el método Fill del objeto SqlDataAdapter el objeto connection al que se ligaba se abre y cierra automáticamente, pero existen ocasiones en que en una msma secuencia de operaciones ejecutamos más de una vez un método Fill de un SqlDataAdapter y entonces, para cada caso se abre y cierra la conexión, pero en este blog expone que para obtener un mejor performance es recomendable abrir y cerrar la conexión manualmente abrirlá al momento de iniciar el primer Fill de un SqlDataAdapter y cerrarla después de ejecutar el último fill del SqlDataAdapter.

En el siguiente link esta el post que leí, además de que expone un ejemplo.


http://davidhayden.com/blog/dave/archive/2005/11/03/2554.aspx

Control Calendario para ASP.NET 1.1 y 2.0

Navegando en la red encontre un control calendario para ASP.NET 2003 y 2005. La descarga incluye una guia de instalación de este control e incluye ejemplos en C# y VB.Net. El control es realmente muy bueno y tiene varios conceptos de configuración.
Pueden desarcargarlo y probarlo de:


http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=FED8B3BE-67E2-4BFC-BE34-404799B17D77

¿En dónde quedo el Enterprise Manager en SQL Server 2005 Express?

Cuando yo instalé SQL Server 2005 versión express, lo primero que yo quería hacer después de la instalación era navegar por las base de datos, conocer su nueva interfaz y ooh!! sorpresa no encontraba una aplicación tipo Enterprise Manager como la de SQL Server 2000, así que me puse a investigar en la web y encontré que Microsoft adicionalmente al motor de base de datos liberó una herramienta grafica llamada: Microsoft SQL Server Management Studio Express (SSMSE).

El link de donde es posible realizar su descarga es:


http://www.microsoft.com/downloads/details.aspx?familyid=82afbd59-57a4-455e-a2d6-1d4c98d40f6e&displaylang=en

mayo 02, 2006

Escucha música en línea.

Cuando estoy en la computadora siempre estoy escuchando música y he aquí un buen sitio de estaciones de radio que mi querida amiga Maru me recomendo. Si tienes una buena conexión a internet podrás disfrutar de las estaciones de música expuestas en esta página y aunque la página es brasileña existen estaciones que pasan música en inglés y otros idiomas.

http://radios.com.br

MP3 a muy bajo precio!!!

Hola! mi primo César encontró un link muy intersante para poder descargar música mp3 a muy bajo costo, incluso pueden escuchar un pequeño fragmento de la canación que desan descagar antes de pagarla, pueden comprar todo un álbum o determinado track de un álbum. Una vez que compran el track o el álbum este se encuentra disponible durante 24 horas para que lo puedan descargar a la hora qu quieran dentro de este lapso.

http://www.mp3sugar.com/

Modelos Entidad Relación disponibles.

Hola! hoy en día casi que cualquier tipo de aplicación que desarrollemos hace persistencia de datos en una base de datos relacional y como desarrolladores de aplicaciones es importante saber modelar la información en un modelo entidad-relación, pues éste diagrama es la base sobre la que comenzaremos a construir nuestra aplicación.

En el siguiente link podremos obtener muy buenas ideas en la construcción de nuestros modelos de Entidad-Relación.

http://www.databaseanswers.org/data_models/index.htm

SQL Server Express 2005

Hola! hace unos días descargué la versión Express de SQL Server y una vez instalado esperaba ver algo así como el Enterprise Manager de SQL Server 2000 y ohh!!! sorpresa no lo había, así que me puse a buscar en la web y encontré una página que expone todos los elementos que debes descargar para poder configurar y comenzar a utilizar el SQL Server 2005 Express.

href="http://www.ukaug.co.uk/TPExpress.asp">