SQL - NO CURSOR-SOLO TSQL

 
Vista:
sin imagen de perfil

NO CURSOR-SOLO TSQL

Publicado por DALSOM (195 intervenciones) el 11/05/2009 20:02:49
HOLA A TODOS, NUEVAMENTE.

A VER, HE ESTADO INVESTIGANDO ESTA MAÑANA, Y VI MUCHAS COSAS QUE ME AYUDARON, Y ENTRE OTRAS ME TIENEN PENSANDO EN UNA NUEVA FORMA.

A VER COMO HARIAN ESTO SIN UN FETCH. TENGO UNA TABLA DE n CAMPOS char() Y varchar(), MUCHOS COMO PARA DIGITAR UN UPDATE POR CADA CAMPO.

TENGO QUE ACTUALIZAR TODOS LOS CAMPOS QUE SEAN char, Y CUYO VALOR SEA UN ASTERISCO (*) A ESPACIOS EN BLANCO, EN TODAS LAS FILAS.

PARECE SENCILLO. PERO CUANDO LOS CAMPOS DE UNA TABLA SON 50, 100, o 200 ES DIFERENTE. POR LO QUE PENSE EN DOS SOLUCIONES:

1. DIGITAR UPDATES PARA CADA CAMPO, QUE ES MUY TEDIOSO.

2.SUBIR LOS NOMBRES DE CAMPOS DE TIPO CHAR A UN CURSOR, Y LUEGO HACER UN CICLO fetch_status DONDE CONSTRUYO EL UPDATE PARA CADA CAMPO, Y LOS EJECUTO CON exec (<comando>) QUE SON MUCHO MENOS LINEAS DE CODIGO (PARECIA LO IDEAL).

PERO ENTONCES VI UN COMENTARIO DE ALGUIEN QUE PREGUNTO SOBRE LOS CURSORES, Y VARIOS LE RESPONDIERON QUE NO SON RECOMENDABLES, QUE DEBERIA HACERLO CON TSQL, YA QUE CON EL CURSOR BAJA MUCHO EL PERFORMANCE Y PUEDE COLGARSE EL SERVIDOR.

COMO PODRIA HACER UN UPDATE PARA QUE SI EL VALOR DE CADA CAMPO EN CADA FILA ES UN ASTERISCO, LO SUSTITUYA POR EL VALOR DESEADO, EN CADA CAMPO DE CADA FILA? MAS GRAFICAMENTE :

TablaN
F1 F2 F3 F4 .... Fn
1 AA * BB * .... Y1
2 * X1 * DD .... *
3 C3 DL DS K3 .... *

DE LA FORMA 1 SERIA ASI :

update tablaN set f1 = ' ' where F1 = '*'
update tablaN set f2 = ' ' where F2 = '*'
update tablaN set f3 = ' ' where F3 = '*'
....
update tablaN set fn = ' ' where Fn = '*'

DE LA FORMA 2 SERIA CON UN :

Declare cursor curFields as
select column_name from tempdb.INFORMATION_SCHEMA.columns
where TABLE_NAME = 'Tablas' and data_type in('char','varchar')
open cursor curfields
fetch next into @cfn -- un char(128) como maximo nombre de campo.
do while @fetch_status = 0
begin
exec ('update tablaN set ' + rtrim(@table_name) + '= space(0)
where ' + rtrim(@table_name) + ' =' + ''' + '*' + ''' )
end
deallocate curfield
close curfield

QUE HARIA BAJAR ENORMEMENTE EL PERFORMANCE DEL SERVIDOR.

YA QUE LO EXPLIQUE LO MEJOR QUE PUDE, QUE OTRA OPCION ME RECOMIENDAN?

DE ANTEMANO, GRACIAS POR LEER MI EXTENSA EXPLICACION.
ACEPTO CUALQUIER SUGERENCIA.

GRACIAS.
DALSOM
REP. DOM.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:NO CURSOR-SOLO TSQL

Publicado por pacopaz (143 intervenciones) el 11/05/2009 20:40:45
Si no quieres hacer cursores, que en suma, para mi, es la mejor opción, puedes hacer tablas temporales o variables tipo tabla, de forma que tengan dos columnas, una como identificador secuencial y otra con el nombre de la columna.
Luego, hacer un loop que vaya del 1 al número máximo de la columna identificador de la tabla temporal. Luego, un select into a una variable que mantenga el nombre de la columna y luego mandar a ejecutar tu sql dinámico, todo esto, para cada iteración.
Para serte franco, sólo ocuparías más memoria, de forma innecesaria si siguieras esta opción. Si fuera una tabla temporal, estarías accediendo a disco duro, lo cual lo hace más lento y si fuera a una variable tipo tabla el acceso es a memoria física, justo como el cursor, pero sería más la memoria que utilizarías, debido a la columna adicional de identificador.
Los cursores no son tan mala idea. La verdad es que el manejo secuencial de registros es difícil llevarlo acabo si no es a través de un cursor. Por ahí tuvimos alguna discusión al respecto Isaías y un servidor, hará poco menos de un año. El argumento es que efectivamente los cursores pueden reducir el desempeño, pero son una buena técnica. Casos como el de mysql que no los implementaban, eran sujetos de crítica, debido a que se requería de mucho esfuerzo, para la lectura secuencia y la verdad es que sql server, en su implementación de fábrica, ocupa muchos cursores.
En tu caso, son 200 iteraciones cuando más. Cada update debería generar un segundo de espera, así que creo que el script completo no debe tardar más de unos 3 minutos por tabla. Por tanto, el desempeño, si acaso se redujera considerablemente durante la ejecución, dudo que sea problema si se hace a una hora en la que pocos o nadie estén accesando. Si lo haces con su previo respaldo de información, para evitar tener que incluir algún rollback, el resultado puede traerse de forma rápida, incluso usando un cursor para su ejecución. Y el uso del deallocate es algo que no puedo menos que aplaudir.
Sinceramente, la decisión te está llevando más tiempo que su ejecución.

Saludos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

RE:NO CURSOR-SOLO TSQL

Publicado por DALSOM (195 intervenciones) el 11/05/2009 22:37:34
GRACIAS POR RESPONDERME.

VERAS, EL PROBLEMA ES QUE ESTA ITERACION SE HARIA CADA 10 MINUTOS EN FORMA AUTOMATICA POR UN JOB. ADEMAS, ESTARIA EN UN SERVIDOR QUE BIEN SEA SOLO PARA SQL EXCLUSIVAMENTE, EL SQL LE DEMANDA LA TODOS SUS RECURSOS DE MEMORIA Y NO SE QUE DECIRTE DEL DISCO.

PERO COMO DICES, ME HA TOMADO MAS TIEMPO LA DECISION DE QUE HACER, QUE HACERLO, POR LO QUE ME TOME 5 MINUTOS EN EXCEL Y LO IMPLEMENTE DE LA FORMA QUE TENGO QUE DIGITAR Update POR Update ESPECIFICANDO CADA CAMPO POR CADA Update, Y POR EL MOMENTO, NO SE SI INDEFINIDAMENTE, SE QUEDARA ASI.

VI ESA DISCUSION A LA QUE TE REFIERES, Y FUE LO QUE ME HIZO PENSAR EN BUSCAR UNA MEJOR SOLUCION, A TENER 200 Update'S O MAS EN MI QUERY.

COMO SEGUN ESTUBE LEYENDO, EL 99% DE LAS COSAS SE RESUELVEN CON TSql, POR LO QUE LO ESTABA INTENTANDO MEJORAR MI CODIGO.

SALUDOS,
DALSOM.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:NO CURSOR-SOLO TSQL

Publicado por pacopaz (143 intervenciones) el 11/05/2009 23:25:03
Ah caray, no pues si es frecuente la actualización.
La verdad es que si ya lo hiciste a través de queries, no haría falta moverlo, aunque el archivo de log si estaría en constante incremento, así que sería bueno también un plan de mantenimiento que se encargue de eso también, además de un buen plan de respaldos.
Se me acaba de ocurrir que si lo que quieres es buscar constantemente los asteriscos, por que no cambiar el valor previo a ser guardado? Con eso evitarías hacer un trabajo adicional. No se si tengas la manera de cambiar ese proceso, pero sería bueno que le dieras una revisada, para evitarte el cambio asincrónico.

Saludos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

RE:NO CURSOR-SOLO TSQL

Publicado por DALSOM (195 intervenciones) el 12/05/2009 14:17:45
SI, SE ME OCURRIO ESO, Y REEMPLAZAR LOS QUE YA ESTABAN. ASI SOLO HACIA EL TRABAJO UNA SOLA VEZ. PERO ME ES PERMITIDO SOLO DESARROLLAR NUEVOS CODIGOS, NO CAMBIAR LOS EXISTENTES.

POR EL MOMENTO, PUES, YA ESTA. AUNQUE NO QUEDE CONFORME, Y ME EMOCIONO MUCHO LA IDEA DE QUE PODIA HACERLO CON UNA SOLA SENTENCIA O LINEA, TODO AL MISMO TIEMPO, AUN NO HE PODIDO.

EN CUANTO AL LOG, PUES NO TENGO ACCESO A EL CON MI USUARIO. PERO, SI ESO DEBE DE CREAR UN LOG BIEN GRANDE. PERO AUN NO SE COMO SE MANEJAN POR ACA CON ESO.

SALUDOS, DESDE REP. DOM.
DALSOM.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:NO CURSOR-SOLO TSQL

Publicado por Eduardo Baeza O. (1 intervención) el 16/06/2009 16:38:32
Hola, prueba con los triggers, al momento de insertar o updatear revisa si trae '*' y lo reemplazas por ''

espero te ayude
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar