none
update con join

    General discussion

  •  UPDATE DBO.CONTABILIDAD 
    	SET DBO.CONTABILIDAD.Filler='00'
    	FROM DBO.CONTABILIDAD C
    	INNER JOIN CREDITO CR
    	ON  C.CodOperacion=CR.CodOperacionActiva
    	WHERE 1=1
    	AND CR.CodProducto<>'000113'
    	AND CR.CodSubProducto<>'000105'
    	
    	UPDATE DBO.CONTABILIDAD 
    	SET DBO.CONTABILIDAD.Filler='01'
    	FROM
        DBO.CONTABILIDAD c
            INNER JOIN CREDITORECUPERACION CR
    	ON  C.CodOperacion=CR.CodOperacionActiva 
    	
        WHERE c.codoperacion IN
        (
    	SELECT oac.codoperacionactiva 
    	FROM  OPERACIONACTIVACALENDARIO  oac
    	INNER JOIN 
    		(SELECT codoperacionactiva,MAX(NumCuotaCalendario) AS maxcuota 
    		FROM OPERACIONACTIVACALENDARIO 
    		GROUP BY codoperacionactiva ) tbl
    		ON oac.codoperacionactiva = tbl.codoperacionactiva 
    			AND oac.NumCuotaCalendario=tbl.maxcuota
    			AND (SELECT FechaHoy from FechaCierre)=OAC.FechaCancelacionCuota
    			
    	WHERE estadocuotacalendario IN ('C','G')
        ) 
         AND  CR.EstadoRecuperacion='H'

    saludos tengo un procedure con muchas query similares a esta, lo que quiero saber es si esta biene scrita la quey o puedo hacerla de otra manera porque son como 10 de esas actualizaciones mi duda nace en esta parte

     UPDATE DBO.CONTABILIDAD
    SET DBO.CONTABILIDAD.Filler='00'
    FROM DBO.CONTABILIDAD C....

    antes lo hacia asi

     UPDATE CONTABILIDAD
    SET  Filler='00'
    FROM DBO.CONTABILIDAD C.  ....

    aparentemente funciona bien,,,pero me di cuenta que poner contabilidad simplemnete es como que la tabla estuviera suelta, no relacionada a ningun alias asi que no sabia si esto era correcto,espero me puedan ayudar o aconsejar.


    adicionalmente no se si debo poner el prefijo dbo
    • Edited by Augusto C Monday, September 10, 2012 7:49 PM
    • Changed type Eder CostaOwner Thursday, September 27, 2012 1:39 PM
    Monday, September 10, 2012 7:44 PM

All replies

  • Hola que tal . . . El prefijo dbo no es necesario...cuando en un UPDATE cruzas varias tablas, tienes que especificar el alias de la tabla donde vas a hacer el UPDATE, xq si no la actualización se hará en TODA LA TABLA y no a los registros que estás seleccionando con tus JOIN ( bueno, al menos eso me pasó a mi, si estoy mal que alguien me corrija ) como te muestro a continuación: 

    UPDATE C -- <- AQUI PONES EL ALIAS
    	SET C.Filler='00'
    	FROM DBO.CONTABILIDAD C
    	INNER JOIN CREDITO CR
    	ON  C.CodOperacion=CR.CodOperacionActiva
    	WHERE 1=1 --<- AQUI NO ENTIENDO ESTE FILTRO
    	AND CR.CodProducto<>'000113'
    	AND CR.CodSubProducto<>'000105'
    	
    	UPDATE C -- <-- AQUI TAMBIEN, YA SEA C O CR
    	SET DBO.CONTABILIDAD.Filler='01'
    	FROM
        DBO.CONTABILIDAD c
            INNER JOIN CREDITORECUPERACION CR
    	ON  C.CodOperacion=CR.CodOperacionActiva 
    	
        WHERE c.codoperacion IN
        (
    	SELECT oac.codoperacionactiva 
    	FROM  OPERACIONACTIVACALENDARIO  oac
    	INNER JOIN 
    		(SELECT codoperacionactiva,MAX(NumCuotaCalendario) AS maxcuota 
    		FROM OPERACIONACTIVACALENDARIO 
    		GROUP BY codoperacionactiva ) tbl
    		ON oac.codoperacionactiva = tbl.codoperacionactiva 
    			AND oac.NumCuotaCalendario=tbl.maxcuota
    			AND (SELECT FechaHoy from FechaCierre)=OAC.FechaCancelacionCuota
    			
    	WHERE estadocuotacalendario IN ('C','G')
        ) 
         AND  CR.EstadoRecuperacion='H'

    Porque no nos proporcionas los scripts de creación de tus tablas ??  Está medio confuso todo porque no muestras que resultados esperas actualizar y en tu consulta SELECT FechaHoy from FechaCierre, no comprendo para que la necesitas.

    SALU2 ! !

    Monday, September 10, 2012 8:30 PM
  • Saludos una consulta  es verdad lo que se comenta aqui que si no pongo el alias se modifica toda la tabla?.añguien tiene la teorà de como funciona el

    update

    from

    join

    Saludos

    Friday, September 14, 2012 5:47 PM
  • Me pasó y tuve que reprocesar varias estadísticas( errores que vas a aprendiendo de ellos ).. te sugiero algo, primero haz tu SELECT de tus datos que esperas actualizar, luego haz el update con el nombre completo de tu tabla, y haces la comparación de los datos que actualizó y tu SELECT, obviamente esto hazlo con una BD de datos de prueba o que no sea la que está en PRODUCTIVO para que no le afectes y comentas los resultados.


    Friday, September 14, 2012 6:10 PM
  • hola chancrovsky

    lo que pasa es que justamnete para hacer el update tengo que hacer los join de esas tablas que ahi posteo , entonces mi pregunta serìa si hya otra técnica para hacerlo porque yo solo conozco esa.

    Friday, September 14, 2012 7:05 PM
  • Sin conocer las estructuras de tus tablas y sin conocer los datos que quieres actualizar me atrevo a darte una sugerencia de tus UPDATEs de la siguiente manera : 

    UPDATE C -- <- AQUI PONES EL ALIAS
    	SET C.Filler='00'
    	FROM CONTABILIDAD C
    	INNER JOIN CREDITO CR
    	ON  C.CodOperacion=CR.CodOperacionActiva
    	WHERE 1=1 --<- AQUI NO ENTIENDO ESTE FILTRO
    	AND CR.CodProducto<>'000113'
    	AND CR.CodSubProducto<>'000105'
    	
    	UPDATE c -- <-- AQUI TAMBIEN, YA SEA C O CR, EN ESTE CASO ES C
    	SET c.Filler='01'
    	FROM DBO.CONTABILIDAD c
        INNER JOIN CREDITORECUPERACION cr
    	ON c.CodOperacion=cr.CodOperacionActiva 
    	INNER JOIN (
    		SELECT oac.codoperacionactiva 
    		FROM  OPERACIONACTIVACALENDARIO  oac
    		INNER JOIN 
    		(
    			SELECT codoperacionactiva,MAX(NumCuotaCalendario) AS maxcuota 
    			FROM OPERACIONACTIVACALENDARIO 
    			GROUP BY codoperacionactiva 
    		) tbl
    		ON oac.codoperacionactiva = tbl.codoperacionactiva 
    		AND oac.NumCuotaCalendario=tbl.maxcuota
    		AND estadocuotacalendario IN ('C','G') -- <- este campo no se a que tabla pertenece
    		INNER JOIN FechaCierre fc ON oac.FechaCancelacionCuota = fc.FechaHoy -- <-Aqui tampoco entiendo, es la fecha de Hoy ? no puedes tomar GETDATE() ????
        ) as aux ON aux.codoperacionactiva = c.codoperacion 
        AND cr.EstadoRecuperacion='H'
    
         

    Ahora, como te comentaba anteriormente te sugiero que hagas un SELECT de todo el query antes de hacer el UPDATE para revisar si te devuelve los datos que quieres actualizar, es lo que yo hago y me funciona a la perfección antes de hacer un UPDATE tan complejo:

    SELECT * 
    	FROM CONTABILIDAD C
    	INNER JOIN CREDITO CR
    	ON  C.CodOperacion=CR.CodOperacionActiva
    	WHERE 1=1 --<- AQUI NO ENTIENDO ESTE FILTRO
    	AND CR.CodProducto<>'000113'
    	AND CR.CodSubProducto<>'000105'
    	
    	SELECT *
    	FROM CONTABILIDAD c
        INNER JOIN CREDITORECUPERACION cr
    	ON c.CodOperacion=cr.CodOperacionActiva 
    	INNER JOIN (
    		SELECT oac.codoperacionactiva 
    		FROM  OPERACIONACTIVACALENDARIO  oac
    		INNER JOIN 
    		(
    			SELECT codoperacionactiva,MAX(NumCuotaCalendario) AS maxcuota 
    			FROM OPERACIONACTIVACALENDARIO 
    			GROUP BY codoperacionactiva 
    		) tbl
    		ON oac.codoperacionactiva = tbl.codoperacionactiva 
    		AND oac.NumCuotaCalendario=tbl.maxcuota
    		AND estadocuotacalendario IN ('C','G') -- <- este campo no se a que tabla pertenece
    		INNER JOIN FechaCierre fc ON oac.FechaCancelacionCuota = fc.FechaHoy -- <-Aqui tampoco entiendo, es la fecha de Hoy ? no puedes tomar GETDATE() ????
        ) as aux ON aux.codoperacionactiva = c.codoperacion 
        AND cr.EstadoRecuperacion='H'
    
         
    Ojala te sirva

    Friday, September 14, 2012 7:34 PM
  • Prueba esto

    UPDATE DBO.CONTABILIDAD 
    	SET DBO.CONTABILIDAD.Filler='00'
    	FROM DBO.CONTABILIDAD C
    	INNER JOIN CREDITO CR
    	ON  C.CodOperacion=CR.CodOperacionActiva
    	WHERE 1=1
    	AND CR.CodProducto<>'000113'
    	AND CR.CodSubProducto<>'000105'
    	
    	UPDATE DBO.CONTABILIDAD 
    	SET DBO.CONTABILIDAD.Filler='01'
    	FROM
        DBO.CONTABILIDAD c
            INNER JOIN CREDITORECUPERACION CR
    	ON  C.CodOperacion=CR.CodOperacionActiva 
    		INNER JOIN (
    	SELECT oac.codoperacionactiva 
    	FROM  OPERACIONACTIVACALENDARIO  oac
    	INNER JOIN 
    		(SELECT codoperacionactiva,MAX(NumCuotaCalendario) AS maxcuota 
    		FROM OPERACIONACTIVACALENDARIO 
    		GROUP BY codoperacionactiva ) tbl
    		ON oac.codoperacionactiva = tbl.codoperacionactiva 
    			AND oac.NumCuotaCalendario=tbl.maxcuota
    			AND (SELECT FechaHoy from FechaCierre)=OAC.FechaCancelacionCuota
    			
    	WHERE estadocuotacalendario IN ('C','G')
        ) T1
    	ON T1.codoperacion = c.codoperacion
        WHERE CR.EstadoRecuperacion='H'

    No pude analizar correctamente la query para decirte con seguridad si devuelve el mismo resultset o no, pero lo que intente hacer es convertir tu clausula IN en una union directa, ya que el IN por cada valor que retorne tu subquery producirá un IO en las paginas de datos, en cambio la union una sola vez lo hará. Si no compila puedes corregirlo evitando el IN.

    Monday, September 17, 2012 10:23 PM
  • que es un io??

    esop varia el resultado final?

    gracias

    Tuesday, September 18, 2012 12:09 AM
  • Lo expreso mejor con el termino "lecturas logicas". Fijate en este articulo

    http://www.devtroce.com/2012/07/26/clausula-in-vs-between-and-sql-tunning/

    alli se hace una comparacion entre el IN y el Between, pero igual se puede utilizar para este caso, el IN siempre produce lecturas logicas excesivas..

    Por ejemplo si tienes "campo IN (1, 5, 7,34, 6)" lo que el motor ejecutara realmente es 

    campo = 1

    campo = 5

    campo = 7

    campo = 34

    campo = 6

    Creará 5 predicados.. por eso en tu caso decia que convendria convertir tu IN en un JOIN, aunque ambos devolverán el mismo resultado el JOIN será mas eficiente y rápido

    Tuesday, September 18, 2012 12:30 PM