update una tabla subconsulta sola otra filas diferentes datos consulta con comando actualizar sql sql-server sql-server-2005 tsql optimization

tabla - ¿Es posible realizar múltiples actualizaciones con una sola instrucción UPDATE SQL?



update de una base de datos a otra sql server (5)

En un caso más general, donde podría haber muchos cientos de asignaciones para cada uno de los nuevos valores, crearía una tabla separada de los valores antiguos y nuevos, y luego los usaría en la instrucción UPDATE. En un dialecto de SQL:

CREATE TEMP TABLE mapper (old_val CHAR(5) NOT NULL, new_val CHAR(5) NOT NULL); ...multiple inserts into mapper... INSERT INTO mapper(old_val, new_val) VALUES(''a.1'', ''a1''); INSERT INTO mapper(old_val, new_val) VALUES(''a-1'', ''a1''); INSERT INTO mapper(old_val, new_val) VALUES(''b.1'', ''b1''); INSERT INTO mapper(old_val, new_val) VALUES(''b-1'', ''b1''); ...etcetera... UPDATE tbl SET title = (SELECT new_val FROM mapper WHERE old_val = tbl.title) WHERE title IN (SELECT old_val FROM mapper);

Ambas declaraciones seleccionadas son cruciales. La primera es una subconsulta correlacionada (no necesariamente rápida, pero más rápida que la mayoría de las alternativas si la tabla mapeador tiene miles de filas) que extrae el nuevo valor de la tabla de asignación que corresponde al valor anterior. El segundo asegura que solo se modifiquen aquellas filas que tienen un valor en la tabla de mapeo; esto es crucial ya que de lo contrario, el título se establecerá en nulo para aquellas filas sin una entrada de mapeo (y esos fueron los registros que estaban bien antes de comenzar).

Para algunas alternativas, las operaciones CASE están bien. Pero si tiene cientos o miles o millones de asignaciones para realizar, entonces es probable que exceda los límites de la longitud de la instrucción SQL en su DBMS.

Digamos que tengo una tabla tbl con columnas id y title . Necesito cambiar todos los valores de la columna del título:

  1. de ''a-1'' a ''a1'',
  2. de ''a.1'' a ''a1'',
  3. de ''b-1'' a ''b1'',
  4. de ''b.1'' a ''b1''.

En este momento, estoy realizando dos declaraciones UPDATE:

UPDATE tbl SET title=''a1'' WHERE title IN (''a-1'', ''a.1'') UPDATE tbl SET title=''b1'' WHERE title IN (''b-1'', ''b.1'')

Esto no es en absoluto un problema, si la tabla es pequeña, y la instrucción única se completa en menos de un segundo y solo necesita unas pocas sentencias para ejecutar.

Probablemente lo hayas adivinado: tengo que lidiar con una gran tabla (una afirmación se completa en aproximadamente 90 segundos), y tengo un gran número de actualizaciones para llevar a cabo.

Entonces, ¿es posible fusionar las actualizaciones para que solo analice la tabla una vez? O tal vez, hay una mejor manera de tratar en una situación como esta.

EDITAR: Tenga en cuenta que los datos reales con los que estoy trabajando y los cambios en los datos que tengo que realizar no son tan simples: las cadenas son más largas y no siguen ningún patrón (son datos de usuario, por lo que no hay suposiciones). se puede hacer, puede ser cualquier cosa).


O

Update Table set title = Replace(Replace(title, ''.'', ''''), ''-'', '''') Where title Like ''[ab][.-]1''


Puede usar una declaración y varias declaraciones de casos

update tbl set title = case when title in (''a-1'', ''a.1'') then ''a1'' when title in (''b-1'', ''b.1'') then ''b1'' else title end

Por supuesto, esto causará una escritura en cada registro, y con los índices, puede ser un problema, por lo que puede filtrar solo las filas que desea cambiar:

update tbl set title = case when title in (''a-1'', ''a.1'') then ''a1'' when title in (''b-1'', ''b.1'') then ''b1'' else title end where title in (''a.1'', ''b.1'', ''a-1'', ''b-1'')

Eso reducirá el número de escrituras en la mesa.


Si las transformaciones son tan simples como sus ejemplos, podría hacer la actualización con un poco de manipulación de cadenas:

UPDATE tbl SET title = left(title, 1) + right(title, 1) WHERE title IN (''a-1'', ''a.1'', ''b-1'', ''b.1'')

¿Algo así podría funcionar para ti?


Trabajando sin la respuesta de Jonathan.

UPDATE tbl SET title = new_val FROM mapper WHERE title IN (SELECT old_val FROM mapper) AND mapper.old_val = tbl.title;

Su versión inicial requeriría una gran cantidad de lecturas en la tabla del asignador.