2010-01-29 13 views
27

Si hay:IF UPDATE() en el gatillo del servidor SQL

IF UPDATE (col1) 

... en el gatillo del servidor SQL en una tabla, no se devuelve true sólo si col1 se ha cambiado o ha actualizado?

Tengo una consulta de actualización regular como

UPDATE table-name 
    SET col1 = 'x', 
     col2 = 'y' 
WHERE id = 999 

Ahora lo que mi preocupación es si el "col1" fue 'x' previamente luego otra vez al día para 'x' haría IF UPDATE ("col1") retorno del gatillo Cierto o no ?

Me enfrento a este problema ya que mi consulta de guardado es genérica para todas las columnas, pero cuando agrego esta condición, devuelve True incluso si no cambia ... Por lo tanto, me preocupa qué hacer en este caso si quiero agregar una condición así?

Respuesta

39

Devuelve verdadero si se actualizó una columna. Una actualización significa que la consulta tiene SET el valor de la columna. Si el valor anterior era el mismo que el nuevo valor es en gran medida irrelevante.

UPDATE table SET col = col 

Es una actualización.

UPDATE table SET col = 99 

cuando el col ya tenía el valor 99 también es una actualización.

+11

Tenga en cuenta que en un INSERTAR, la función ACTUALIZADA() devuelve 1 para TODAS las columnas. Por supuesto. – ErikE

+1

¿Y en un BORRAR? – Rory

+4

Resulta que la función UPDATE() no devuelve verdadero para DELETE. http://stackoverflow.com/questions/29286034 – Rory

10

Dentro del activador, tiene acceso a dos tablas internas que pueden ser útiles. La tabla "insertada" incluye la nueva versión de cada fila afectada. La tabla "eliminada" incluye la versión original de cada fila. Puede comparar los valores en estas tablas para ver si realmente cambió el valor de su campo.

+0

En realidad, lo que quería esta verificación para que la ejecución no vaya más allá si no hay actualización –

+0

seguro - utiliza una instrucción if con las tablas insertadas y eliminadas para comparar los valores originales y nuevos - si el campo ha cambiado , haga lo suyo; si no, no lo haga – Ray

2

Lo que debes hacer es verificar los valores diferentes en las tablas insertadas y eliminadas en lugar de usar la versión actualizada() (No olvides dar cuenta de los nulos). O podría dejar de hacer actualizaciones innecesarias.

1

se ahorren el caso "Sin actualización real", es necesario también comprobar en el principio si su consulta ha afectado ninguna fila en absoluto:

set nocount on; -- this must be the first statement! 
if not exists (select 1 from inserted) and not exists (select 1 from deleted) 
    return; 
2

Aquí está una manera rápida para escanear las filas para ver si cualquier columna cambiado antes de decidir ejecutar el contenido de un desencadenador. Esto puede ser útil, por ejemplo, cuando desea escribir un registro de historial, pero no desea hacerlo si realmente no cambió nada.

Utilizamos esto todo el tiempo en los procesos de importación de ETL donde podemos volver a importar los datos, pero si nada realmente cambió en el archivo de origen, no queremos crear un nuevo registro de historial.

CREATE TRIGGER [dbo].[TR_my_table_create_history] 
ON [dbo].[my_table] FOR UPDATE AS 

BEGIN 

    -- 
    -- Insert the old data row if any column data changed 
    -- 
    INSERT INTO [my_table_history] 
    SELECT d.* 
    FROM deleted d 
    INNER JOIN inserted i ON i.[id] = d.[id] 
    -- 
    -- Use INTERSECT to see if anything REALLY changed 
    -- 
    WHERE NOT EXISTS(SELECT i.* INTERSECT SELECT d.*) 

END 

Tenga en cuenta que este disparador particular, asume que su tabla de origen (la activación del gatillo) y la tabla de historial tienen diseños de columnas idénticas.

0
SET NOCOUNT ON; 

    declare @countTemp int 
    select @countTemp = Count (*) from (
    select City,PostCode,Street,CountryId,Address1 from Deleted 
    union 
    select City,PostCode,Street,CountryId,Address1 from Inserted 
    ) tempTable 

    IF (@countTemp > 1) 

Begin 

-- Your Code goes Here 
End 

-- if any of these "City,PostCode,Street,CountryId,Address1" got updated then trigger 

-- will work in " IF (@countTemp > 1) " Code) 
0
cREATE TRIGGER boo ON status2 FOR UPDATE AS 
IF UPDATE (id) 
BEGIN 
SELECT 'DETECT'; 
END; 

UPDATE status2 SET name = 'K' WHERE name= 'T' --no action 
UPDATE status2 SET name = 'T' ,id= 8 WHERE name= 'K' --detect 
0

Esto funcionó para mí

DECLARE @LongDescDirty bit = 0 

Declare @old varchar(4000) = (SELECT LongDescription from deleted) 
Declare @new varchar(4000) = (SELECT LongDescription from inserted) 

if (@old <> @new) 
    BEGIN 
     SET @LongDescDirty = 1 
    END 

Update table 
    Set LongDescUpdated = @LongDescUpdated 

.....

+2

No es seguro, ya que insertado y eliminado puede contener más de un registro si la sentencia UPDATE se aplicó a varios registros. – PapillonUK