Le développeur C # encouragé par la direction à écrire des procédures stockées SQL Server produit souvent des procédures comme celle-ci
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;
Les instructions simples sont plutôt simples et cette méthode leur permet de produire des résultats corrects.
Souvent, ma tâche consiste à migrer ces procédures vers Oracle.
Faisons face aux faits suivants.
- Les différentes tables temporaires de SQL Server sont complètement indépendantes et peuvent avoir n'importe quelle structure ad hoc.
- Les tables communes globales Oracle sont des objets globaux et toutes les utilisations partagent la même structure de table. La modification de cette structure est impossible, alors qu'elle est utilisée n'importe où.
L'une des choses que j'ai apprises d'une base de données Oracle, était d'éviter l'utilisation de tables temporaires chaque fois que cela est possible. Même les performances sur SQL Server bénéficient de telles modifications.
Remplacer les inserts individuels par les syndicats
Dans le cas le plus simple, ce qui précède peut être transformé en quelque chose comme
select case when ... then ... end, ... from table_a where ...
union
select case when ... then ... end, ... from table_b where ...
Order by ...;
Utilisation des fonctions
Les fonctions scalaires et les fonctions table peuvent aider à transformer votre procédure en une seule requête du formulaire ci-dessus.
Expressions de table communes aka Factorisation de sous-requête
L'affacturage de sous-requête est presque le meilleur qu'Oracle puisse offrir pour éviter les tables temporaires. En l'utilisant, la migration de SQL Server vers Oracle est encore une fois assez facile. Cela nécessite SQL Server 2005 et supérieur.
Ces modifications améliorent la version de SQL Server et, dans de nombreux cas, facilitent la migration. Dans d'autres cas, le recours à des tables temporaires globales permet de faire la migration dans un temps borné, mais il est moins satisfaisant.
Existe-t-il d'autres moyens d'éviter l'utilisation de tables temporaires globales dans Oracle?
Réponses:
Une façon de le faire serait les types d'objets , dans ce cas, le type serait analogue à votre
#t1
. Il devrait donc être défini quelque part, mais il ne serait pas nécessaire qu'il soit global, il pourrait même être par schéma ou par procédure. Tout d'abord, nous pouvons créer un type:Configurez maintenant quelques exemples de données:
Et créez une fonction sur ces données en retournant notre type "temporaire":
Et enfin:
Comme vous pouvez le voir, c'est assez maladroit (et utilise des pseudo-fonctions de collection , ce qui est une fonctionnalité obscure dans le meilleur des cas!), Comme je le dis toujours, le portage de DB à DB n'est pas seulement une question de syntaxe et de mots-clés dans leurs dialectes SQL , la vraie difficulté réside dans différentes hypothèses sous-jacentes (dans le cas de SQL Server, que les curseurs sont chers et que leur utilisation est évitée / contournée à tout prix).
la source
Si l' option de cas n'est pas suffisamment flexible, vous pouvez collecter en masse les données dans votre procédure et manipuler le ou les tableaux.
la source
SELECT
est la dernière chose dans un proc stocké T-SQL, c'est ce qu'il renvoie)