O desenvolvedor de C # incentivado pelo gerenciamento a escrever procedimentos armazenados do SQL Server geralmente produz procedimentos 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;
A declaração única é bastante simples e esse método faz com que produzam resultados corretos.
Muitas vezes, minha tarefa é migrar esses procedimentos para o Oracle.
Vamos enfrentar os seguintes fatos.
- Para diferentes tabelas temporárias no SQL Server são completamente independentes e podem ter qualquer estrutura ad hoc.
- As tabelas comuns globais da Oracle são objetos globais e todos os usos compartilham a mesma estrutura de tabela. Modificar essa estrutura é impossível, enquanto é usado em qualquer lugar.
Uma das coisas que aprendi com um dba Oracle foi evitar o uso de tabelas temporárias sempre que possível. Até o desempenho no servidor SQL se beneficia dessas modificações.
Substitua as inserções individuais por uniões
No caso mais simples, o acima pode ser transformado em 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 funções
As funções escalares e as funções com valor de tabela podem ajudar a transformar seu procedimento em uma única consulta do formulário acima.
Expressões de tabela comuns, também conhecidas como Subquery Factoring
O Subquery Factoring é quase o melhor que a Oracle oferece para evitar tabelas temporárias. Usando isso, a migração do SQL Server para Oracle é novamente bastante fácil. Isso requer o SQL Server 2005 e superior.
Essas modificações aprimoram a versão do SQL Server e, em muitos casos, facilitam a migração. Em outros casos, o recurso a tabelas temporárias globais torna possível a migração em um tempo limitado, mas é menos satisfatório.
Existem outras maneiras de evitar o uso de tabelas temporárias globais no Oracle?
Respostas:
Uma maneira de fazer isso seria Object Types , nesse caso, o tipo seria análogo ao seu
#t1
. Portanto, precisaria ser definido em algum lugar, mas não seria global, poderia ser por esquema ou por procedimento. Primeiro, podemos criar um tipo:Agora configure alguns dados de amostra:
E crie uma função sobre esses dados retornando nosso tipo "temporário":
E finalmente:
Como você pode ver, isso é bastante desajeitado (e usa pseudo-funções de coleção , o que é um recurso obscuro na melhor das hipóteses!), Como eu sempre digo, portar de DB para DB não é apenas sintaxe e palavras-chave em seus dialetos SQL , a dificuldade real ocorre em diferentes suposições subjacentes (no caso do SQL Server, que os cursores são caros e seu uso evitado / contornado a todo custo).
fonte
Se a opção de caso não for flexível o suficiente, você poderá coletar os dados em massa no procedimento e manipular a (s) matriz (s).
fonte
SELECT
é a última coisa em um proc T-SQL armazenado, que é o que ele retorna)