Recuerde una experiencia de actualización de datos de Oracle

En el momento crítico, entregado lo antes posible

Recuerde una experiencia de actualización de datos de Oracle

Recientemente, vi un tema interesante y lo compartí con ustedes. Mi solución puede ser bastante estúpida, así que me gustaría ofrecer algunas sugerencias para una mejor solución.

Contenido del tema

Hay un lote de tablas en la base de datos de Oracle (más de 1000) y los caracteres especificados de algunos campos en las tablas deben modificarse a otros caracteres especificados. Los nombres de las tablas son similares, como TABLE0001, TABLE0002, TABLE0003, etc., pero los nombres de las tablas no son continuos. No puede haber tablas TABLE0100, TABLE0200, TABLE0300, etc. Los nombres de campo son similares, como FIELD001, FIELD002, FIELD003, etc. Los nombres de campo de la tabla no son fijos, algunos pueden tener solo un campo, algunos pueden tener más de 100 campos y algunas tablas pueden no tener datos. Ahora es necesario cambiar el contenido de todos los campos en estas tablas que contienen los caracteres "Zhang San" a "Li Si", y los otros caracteres en los campos permanecen sin cambios, por ejemplo: "Zhang San es un buen estudiante" a "Li Si es un buen estudiante".

Al ver tal problema, la primera forma que me viene a la mente es escribir un cursor para que se ejecute repetidamente. Pero a medida que profundicé, descubrí que no era tan simple. (Si desea ver la respuesta, puede pasar a la parte del código al final del artículo) La pregunta se desglosa de la siguiente manera:

El problema de la discontinuidad del
nombre de la tabla El nombre de la tabla no es continuo para determinar si la tabla existe en la base de datos. En este momento, pienso en encontrar estas tablas en la tabla del sistema Oracle USER_TABLES (tabla de usuario) y luego insertarlas en una tabla temporal. Y el número de registros en la tabla también se inserta juntos, lo que es conveniente para filtrar la tabla con 0 registros y reducir la actualización de contenido más tarde.

La declaración de consulta es la siguiente:

DECLARE 
CURSOR CURS ISSELECT TABLE_NAME FROM USER_TABLES 
WHERE TABLE_NAME LIKE 'TABLE%';
v_sql VARCHAR2(4000);
BEGIN
    FOR CUR IN CURS LOOP
    v_sql :=' SELECT  '||''CUR.TABLE_NAME''||',COUNT(1) T_CNT
    INTO TEMP_TABLE FROM '||CUR.TABLE_NAME;
    EXECUTE IMMEDIATE v_sql;
    END LOOP;
END;
END;

Es una lástima que se haya informado un error aquí. El motivo del error es que quiero insertar el nombre de la tabla variable CUR.TABLE_NAME como un carácter en la tabla temporal, para poder consultar la tabla temporal TEMP_TABLE para conocer directamente el número específico de registros en cada tabla, pero en la dinámica La instrucción SQL no tiene éxito y solo puede encontrar otra forma.

Coloque la tabla atravesada en EXCEL para generar automáticamente la declaración de consulta que necesito, como se muestra a continuación:

Recuerde una experiencia de actualización de datos de Oracle

Recuerde una experiencia de actualización de datos de Oracle

La figura EXCEL completa el empalme de la oración de consulta

Luego, inicie la ejecución de estas declaraciones de consulta empalmadas, y luego el volumen de datos de cada tabla se puede consultar e insertar en la tabla temporal TEMP_TABLE. El primer paso se completa con éxito ~


El problema de los campos no arreglados es un poco similar a los nombres de las tablas inconsistentes, pero también hay diferencias Mi enfoque inicial es enumerar todas las columnas y hacer lo que dice.

El código específico es el siguiente:


DECLARE
CURSOR mycur ISSELECT T_NAME 
FROM TEMP_TABLE WHERE T_CNT<>0 ;
myrecord mycur%ROWTYPE;
v_sql1 VARCHAR2(4000);
v_sql2 VARCHAR2(4000);
v_sql3 VARCHAR2(4000);
v_sql4 VARCHAR2(4000);
v_sql5 VARCHAR2(4000);
BEGINOPEN mycur;
LOOP
FETCH mycur INTO myrecord;
EXIT WHEN mycur%NOTFOUND;
v_sql1 :='UPDATE '||myrecord.T_NAME||' SET
FIELD001=REPLACE(FIELD001,''张三'',''李四'')';
v_sql2 :='UPDATE '||myrecord.T_NAME||' SET 
FIELD002=REPLACE(FIELD002,''张三'',''李四'')';
v_sql3 :='UPDATE '||myrecord.T_NAME||' SET 
FIELD003=REPLACE(FIELD003,''张三'',''李四'')';
v_sql4 :='UPDATE '||myrecord.T_NAME||' SET 
FIELD004=REPLACE(FIELD004,''张三'',''李四'')';
v_sql5 :='UPDATE '||myrecord.T_NAME||' SET 
FIELD005=REPLACE(FIELD005,''张三'',''李四'')';
EXECUTE IMMEDIATE v_sql1;
EXECUTE IMMEDIATE v_sql2;
EXECUTE IMMEDIATE v_sql3;
EXECUTE IMMEDIATE v_sql4;
EXECUTE IMMEDIATE v_sql5;
END LOOP;
CLOSE mycur;
END;

El código se puede ejecutar sin problemas, pero se encuentra un problema en él. Esta columna no necesariamente existe. Si no hay ninguna columna en la ejecución, definitivamente se informará un error. El error de la base de datos no se omitirá automáticamente por usted, y se detendrá. ¡Esto no logrará el efecto!

Modificación adicional
Dado que es posible que esta columna no exista, ¿qué tal si me permito juzgarla primero?

Siguiendo esta idea se modifica el código, se consulta la tabla del sistema USER_TAB_COLUMNS si hay un nombre de columna definido en la tabla actualizada, si existe se realiza la actualización y si no existe se salta.

El código específico es el siguiente:

DECLARE
--定义游标
CURSOR mycur IS   
--将临时表TEMP_TABLE中记录数不为0的表查询出来
SELECT T_NAME FROM TEMP_TABLE WHERE T_CNT<>0 ;
myrecord mycur%ROWTYPE;
--定义变量
v_sql1 VARCHAR2(4000);
v_count INTEGER;
--定义列变量,
v_name VARCHAR2(20) := 'TABLE0001';
BEGIN
--打开游标
OPEN mycur;
LOOP
FETCH mycur INTO myrecord;
EXIT WHEN mycur%NOTFOUND;
--从系统表USER_TAB_COLUMNS中查询被更新的表中是否存在定义的列名
SELECT COUNT(*) INTO v_count 
FROM USER_TAB_COLUMNS 
WHERE table_name=myrecord.T_NAME 
and column_name=v_name;
--如果存在执行更新
IF v_count>0 THEN
v_sql1 :='UPDATE '||myrecord.T_NAME||' SET 
'||v_name||'=REPLACE('||v_name||',''张三'',''李四'')';
EXECUTE IMMEDIATE v_sql1;
END IF;
END LOOP;
--结束游标
CLOSE mycur;
END;

El resultado es exitoso, solo necesita modificar la variable v_name. Es muy rápido de ejecutar una vez y solo toma unos 7 segundos.

El
paso final de la optimización posterior se puede automatizar completamente, que consiste en poner todas las columnas en una tabla y ejecutar el cursor en un bucle, siempre que sepa cuántas de las columnas más grandes son, o puede tomar directamente el valor máximo FIELD999 , que puede compararse durante la ejecución. Requiere mucho tiempo, porque en cada ronda tiene que juzgar si la columna existe 999 veces.

Hasta el momento se ha completado la función de rectificar y modificar el contenido de algunos campos en lotes.

Un poco de pensamiento
desencadenó mi pequeño pensamiento sobre este tema, tanto bueno como malo.

Lo bueno es que si te encuentras con un problema que se puede resolver por otros medios, no lo cuelgues de un árbol, no se ha encontrado el primer paso. Si dedica todo su tiempo a este paso, definitivamente superará la ganancia. Lo que es más importante en el trabajo es la eficiencia. Si puede utilizar otros métodos para resolver el problema, puede cambiar el método lo antes posible. Además, refinar el problema también puede hacer que el pensamiento sea más lógico.

Lo malo es que cuando te encuentras con un problema, simplemente escribes el código sin pensar en el resultado de la escritura. En realidad, esto lleva mucho tiempo. Es mejor afilar el cuchillo y no cortar la madera. es mejor pensar en el problema con claridad y luego abordarlo.

Conclusión
Es inevitable que encuentre algunos problemas en el trabajo y en la vida.Cuando puede crear un problema o una cosa a través de su propio pensamiento, la sensación de logro es evidente por sí misma. ¡Quizás esta sea la felicidad de los programadores!

Supongo que te gusta

Origin blog.51cto.com/15057820/2656423
Recomendado
Clasificación