El desarrollador de C # alentado por la gerencia para escribir procedimientos almacenados de SQL Server a menudo produce procedimientos como este
create table #t1 (...);
insert into #t1 Select ... from table_a where ...;
insert into #t1 Select ... from table_b where ...;
update #t1 Set ... = ... where ...
Select * from #t1;
La declaración única es bastante simple y este método hace que produzcan resultados correctos.
A menudo, mi tarea es migrar dichos procedimientos a Oracle.
Seamos realistas los siguientes hechos.
- Las diferentes tablas temporales en SQL Server son completamente independientes y pueden tener cualquier estructura ad hoc.
- Las tablas comunes globales de Oracle son objetos globales y todos los usos comparten la misma estructura de tabla. Es imposible modificar esta estructura, mientras se usa en cualquier lugar.
Una de las cosas que aprendí de un dba de Oracle fue evitar el uso de tablas temporales siempre que sea posible. Incluso el rendimiento en el servidor SQL se beneficia de tales modificaciones.
Reemplazar los insertos individuales por uniones
En el caso más simple, lo anterior se puede transformar en algo como
select case when ... then ... end, ... from table_a where ...
union
select case when ... then ... end, ... from table_b where ...
Order by ...;
Uso de funciones
Tanto las funciones escalares como las funciones con valores de tabla pueden ayudar a transformar su procedimiento en una sola consulta del formulario anterior.
Expresiones de tabla comunes aka Subquery Factoring
Subgery Factoring es casi lo mejor que Oracle tiene para ofrecer para evitar tablas temporales. Usarlo de nuevo la migración de SQL Server a Oracle es bastante fácil. Esto requiere SQL Server 2005 y superior.
Estas modificaciones mejoran la versión de SQL Server y, en muchos casos, facilitan la migración. En otros casos, recurrir a tablas temporales globales permite realizar la migración en un tiempo limitado, pero es menos satisfactorio.
¿Existen otras formas de evitar el uso de tablas temporales globales en Oracle?
Respuestas:
Una forma de hacerlo sería Tipos de objetos , en este caso el tipo sería análogo a su
#t1
. Por lo tanto, tendría que definirse en alguna parte, pero no tendría que ser global, podría ser por esquema o incluso por procedimiento. Primero, podemos crear un tipo:Ahora configure algunos datos de muestra:
Y cree una función sobre estos datos que devuelva nuestro tipo "temporal":
Y finalmente:
Como puede ver, esto es bastante torpe (¡y usa pseudofunciones de colección , que es una característica oscura en el mejor de los casos!), Como siempre digo, la transferencia de DB a DB no se trata solo de sintaxis y palabras clave en sus dialectos SQL , la verdadera dificultad viene en diferentes supuestos subyacentes (en el caso de SQL Server, que los cursores son caros y su uso se evita / evita a toda costa).
fuente
Si la opción de caso no es lo suficientemente flexible, puede recopilar los datos de forma masiva en su procedimiento y manipular la (s) matriz (s).
fuente
SELECT
es la última cosa en un proc almacenado de T-SQL, que es lo que devuelve)