Lluvia…

Ha estado lloviendo toda la mañana, desde anoche.
Lluvia imprevista, lluvia con sabor a sal, lluvia de nubes oscuras…
A pesar del verano, aun con el sol ardiente… y recien es enero…
Afuera está seco, cierro lo ojos y siento la lluvia, caliente.

Camino hacia adelante, pero se sabe que a veces ir hacia adelante es una forma de retroceder, pero es mejor la idea de seguir adelante de mentira que retrocerder de verdad… camino recogiendo imagenes, formando escenas, creando situaciones, cambiando gestos, agregando palabras, enmarcandolos en recuerdos para alegrarme de ellos cuando me detenga a descansar, cuando sueñe que estoy dentro de ellos…

En los sueños no llueve, siempre es primavera y noches de luna llena, magicas y apasionantes, y toman vida propia todos los recuerdos, tan real que siento que solamente es alli donde vivo, natural y libre…
Pero un rayo de agua corta el paraiso… luego otro.. al rato uno mas… se desvanece el sueño, se decoloran las imagenes, se apagan las voces…

Abro los ojos y de nuevo tengo esa sensacion salada y tibia en la cara…

Tienes que regresar

Estoy aqui sin aterrizar…
No veo el suelo, solo nubes…
con la radio sin señal,
sin rumbo y motores apagados.

Aun asi, no aterrizaré.
Quiero caer como una piedra.
Ver directamente a la tierra,
que no quiso soltarme al viento,
sentir que va abriendo sus fauces
para no dejarme escapar de nuevo.

Quiero estar en el aire
pero me está llamando la tierra:
“Tienes que regresar”
Y me resistiré hasta el ultimo segundo,
creer que vuelo cuando esté cayendo
Y todo se convierta en un sueño…

¡Día del Perú!

¡Seguimos 28 de julio! y continuamos descansando, como escuche alguna vez: “los de computo no hacen nada, solo se rascan la barriga…”
¡hey! ¡un momento! ¿como que nada? Tengo un poema:

Poema 0×002
Abrazarte,
Sentir tu aroma en el aire
y transformar en palabras mi amor por ti…

Escúchame,
Sentir tus labios al hablarte sin besarte
y convertir un segundo en mil vidas para quererte…

Mírame,
Que no hace sol ni lluvia, solo es verte y no verte.
No hay dia ni noche, sino estar contigo y verte alejada.
tampoco dulce o amargo, es sentir tu amor y tu indiferencia.

¿Sabes? Es un dulce dia con sol.

Besarte,
Y que las mil vidas demoren eso, mil vidas.
Y sentir tu amor dulce o amargo,
estar contigo dia y noche,
verte en el sol y en lluvia.

Quiero decir, amarte.

Feriado por fiestas patrias….

Dos dias para esribir… esta vez poemas, poemas que los tenia escrito hace algunas semanas, algunas semanas que se pueden contar en meses…

Poema 0×001
El tiempo pasa… y trae cambios, tu cambias tambien.
Nada que venga podemos manejarlo, solo seguir adelante.
Tu mirada ya no brilla como lo era antes.
Creo que para mi ya no brillan.
Asi eres tú.

La ciudad ya no es la misma ciudad de antes.
Es dificil volver a mirarte a los ojos
Asi eres tu.
Pero mi corazon es tuyo…
Te quiero.
Seguiré así.

Hace tiempo, aunque no hace mucho tiempo
Todo era diferente, realmente hermoso.
Era dulce sentir tus brazos, tu aroma.
Asi eres tú.

Cada mañana, al amanecer
Sonreía pensando en ti. Y sonrio al pensar en ti.
Eres única, te lo dije mil veces.
Asi eres tú.

Escuchame, léeme.
No cambies, no me hagas caso.
Asi eres tu. Asi te conocí. Asi eres mi amor.
Seguiré así.

Felicidades viejo!

Un domingo comun y silvestre, programando desde temprano, estudiando e investigando como un loco programador desde hace años…
Y ayer fue -todavia- mi dia: el dia del papacito, jaja. Hoy es el dia del padre, y me siento contento de poder saludar a mi papá Emilio y tambien saludar a todos los padres en este dia tan especial.

De hecho mis padres viven lejos, y asi hay muchos casos, aunque no los llame, tengan presente que los recuerdo siempre, y sus consejos aun suenan en mi mente cuando son necesarios.
Gracias y saludos.

Búsqueda de “huecos” en una secuencia de numeros – SQL Server

En esta ocasión veremos la búsqueda vacíos o huecos en una secuencia de numeros, esto es especialmente util cuando generamos los identificadores para una tabla, pero no para reusar el numero eliminado, sino para detectar que elementos fueron eliminados en un rango de numeros determinado.
CONSIDERACIONES DE RENDIMIENTO: Debe usarse para un rango de numeros, que no pase de aproximadamente de 10000, debido a que se crea una tabla temporal para crear una lista completa de numeros para tomarlas como base en la busqueda de numeros faltantes.
Veamos en codigo:


-- Realiza una busqueda de "huecos" en una secuencia de numeros, es decir, en identificadores faltantes en una serie dada.

set nocount on;
-- asumimos que es una tabla de sistema base.
create table #_series(
id int primary key,
txt nvarchar(24)
);
-- dejamos intencionadamente de insertar el id #4 y #8 para realizar su busqueda.
insert into #_series values(1, 'Notepad');
insert into #_series values(2, 'Office 2010');
insert into #_series values(3, 'Visual Studio 2010');
insert into #_series values(5, 'Windows 7');
insert into #_series values(6, 'Jaguar SFAX-25');
insert into #_series values(7, 'Hyper-V');
insert into #_series values(9, 'Windows Server 2008 R2');
print 'inicio '+convert(nvarchar(50), getdate(), 121);
-- un vistazo.
select * from #_series;
-- de hecho, no usaremos cursores.
declare @n1 int;
declare @nn int;
-- conseguir el primer y el ultimo numero de la secuencia
set @n1 = (select top 1 id from #_series order by id asc);
set @nn = (select top 1 id from #_series order by id desc);
-- crear una tabla temporal para la lista de identificadores generados interpolando el n1 y nn.
create table #_se(
id int
);
print 'iniciar tabla id '+convert(nvarchar(50), getdate(), 121);
declare @i int;
set @i = @n1;
while @i <= @nn
begin
insert into #_se values (@i);
set @i = @i + 1;
end
print 'fin tabla id '+convert(nvarchar(50), getdate(), 121);
-- conseguir los ids huecos
select id from #_se
where id not in (select id from #_series);
-- limpieza
drop table #_se;
drop table #_series;

NOTA: Si volvemos a ejecutarlo, pero en vez de poner el id 9 al ultimo insert ponemos 900000, se demora en crear la lista mas de un minuto (en mi equipo). Para rangos menores de 1000 demora menos de 1 segundo.

Convertir filas a columnas en SQL Server

Muchos temas los pasamos por alto mientras no lo necesitamos… hasta que lo tenemos encima y nos ponemos a escarbar en nuestro cerebro busando una solucion.

Esta semana tenia que hacer un listado de guias con sus respectivos documentos de cobranza, por lo general tienen uno, pero a veces tienen 2 o mas, siendo anuladas o de otro tipo de comprobante, lo que implica que los documentos estan distribuidos en diferentes tablas.

Hice un ejemplo primario para lograr el objetivo deseado: convertir las filas en columnas, en este caso especifico, mostrar los detalles de un registro principal (maestro) como columnas adicionales.

Las soluciones que encontre en internet implicaban usar cursores, consultas dinamicas larguisimas, y sobre todo un codigo bastante complejo, pero me sirvió de base para construir una solucion mas sencilla, de hecho el consumo de recursos puede mantenerse igual (no he probado este tema), pero la forma de hacerlo es mas entendible a simple vista.  Y tambien es necesario poner un limite en el numero de detalles, pero nuevamente es facil de aumentar esa capacidad, eso veremos en el ejemplo.

La idea fue hacer unas tablas temporales para un grupo musical y sus integrantes y mostrar en una sola fila cada grupo y sus integrantes como filas adicionales. Veamos en codigo, que se nos da mejor :D

-- grupo musical
create table #_grupo(
id int identity(1, 1) primary key,
nombre nvarchar(32) not null
);

-- integrantes del grupo
create table #_cantante(
id int identity(1, 1) primary key,
grupoid int not null,
nombre nvarchar(32),
ok bit
);

-- tabla de resultados.
-- se debe asumir un limite. en este caso 6 integrantes como maximo.
create table #_ext(
id int primary key,
nombre nvarchar(32) not null,
i1 nvarchar(32) null,
i2 nvarchar(32) null,
i3 nvarchar(32) null,
i4 nvarchar(32) null,
i5 nvarchar(32) null,
i6 nvarchar(32) null
)
-- rellenado de datos.
declare @i int;
insert into #_grupo(nombre) values ('Aroma');
set @i = scope_identity();
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Teresa', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Susan', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Cinthya', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Liz Karen', 0);

insert into #_grupo(nombre) values ('Rihanna');
set @i = scope_identity();
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Rihanna', 0);

insert into #_grupo(nombre) values ('Agua Bella');
set @i = scope_identity();
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Marina', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Giuliana', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Esther', 0);

insert into #_grupo(nombre) values ('Tremendas');
set @i = scope_identity();
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Vanesa', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Milagros', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Debora', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Diana', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Karla', 0);

insert into #_grupo(nombre) values ('Alma Bella');
set @i = scope_identity();
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Maricarmen', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Alheli', 0);

insert into #_ext(id, nombre) select id, nombre from #_grupo;
-- visualizaciones basicas
--select * from #_grupo;
--select * from #_cantante;
-- un conteo
--select g.id, g.nombre, 'integrates' = count(c.id) from #_grupo g
--inner join #_cantante c on g.id = c.grupoid
--group by g.id, g.nombre;
-- la vista general que queremos invertir
--select g.id, g.nombre, c.nombre from #_grupo g
--inner join #_cantante c on g.id = c.grupoid;

-- agrupacion de detalles en el maestro.
declare @k int;
declare @query nvarchar(1024);
set @k = 1;
while @k <= 6
begin
-- query base para construir el query dinamico.
-- update #_ext set i1 = c.nombre from #_cantante c where c.grupoid = #_ext.id and c.ok = 0;
set @query = N'update #_ext set i' + ltrim(rtrim(convert(nvarchar(8), @k))) + N' = c.nombre from #_cantante c where c.grupoid = #_ext.id and c.ok = 0';
execute(@query);
-- query base para construir el query dinamico.
--update #_cantante set ok = 1 from #_ext where i1 = #_cantante.nombre;
set @query = N'update #_cantante set ok = 1 from #_ext where i' + ltrim(rtrim(convert(nvarchar(8), @k))) + N' = #_cantante.nombre';
execute(@query);
set @k = @k + 1;
end
-- mostrar el resultado deseado
select 'grupo'= nombre, 'principal'=i1, '2º voz'=i2, 'bailarina 1'=i3, 'bailarina 2'=i4, 'bailarina 3'=i5, 'bailarina 4'=i6 from #_ext;
-- ser buenos ciudadanos.
drop table #_grupo;
drop table #_cantante;
drop table #_ext;

Bienvenido

Si eres de los que se pasa el dia (y la noche) con:

  • Visual Studio
  • SQL Server

Entonces eres uno de los nuestros, un guerrero Jaguar.

La mision es crear una libreria de clases, para el manejo de una Farmacia y luego extenderlo hacia una clínica completa, mostrando una adecuado modelo de desarrollo de software, -aunque no seguiremos alguno en especial- aplicaremos lo mejor de lo reconocido como bueno.

En la antiguedad un guerrero debia de cazar un jaguar él solo para obtener el titulo de guerrero Jaguar. Ahora debemos cazar al bipolar bit, para lograr la medalla.

Bienvenido de nuevo.