2017-01-12 3 views
4

Comme la plupart d'entre vous le savez, SSIS a du mal à lire les métadonnées chaque fois qu'une procédure stockée avec des tables temporaires est utilisée comme OleDbSource. Auparavant, cela pouvait être facilement évité en ajoutant SET FMTONLY OFF; avant la déclaration de l'EXEC. L'inconvénient de ceci est que la procédure stockée est exécutée pendant la validation et cela peut prendre un certain temps. Depuis SQL 2012, nous pouvons utiliser WITH RESULT SETS pour spécifier les colonnes et leurs types de données. SSIS va le ramasser et tout va bien en SQL.Génération de packages SSIS avec BIML utilisant des procédures stockées avec des tables temporaires

Toutefois, je souhaite générer un package avec BIML qui utilise une telle procédure stockée en tant que source et je n'arrive pas à le faire fonctionner. Supposons que j'ai une procédure stockée appelée 'dbo.csp_MyCsp' qui utilise une table temporaire appelée '#MyTempTable' avec 1 colonne 'ColA int'. Je suis en train de générer un OleDbSource avec les éléments suivants (similaires) Code BIML:

<OleDbSource ConnectionName="MyConnection" Name="OLE_SRC Test"> 
    <DirectInput> 
     EXEC dbo.csp_MyCsp 
     WITH RESULT SETS 
     (
      ([Col1] int) 
     ) 
    </DirectInput> 
</OleDbSource> 

Je reçois une erreur qui dit « #MyTempTable objet non valide ». La chose étrange est, si j'ouvre un paquet et que je colle dans ce code dans mon OleDbSource, cela fonctionne sans aucune erreur. J'ai l'intuition que l'étape de validation de SSIS et BIML est différente.

L'un de vous a-t-il une solution appropriée? Je ne peux pas utiliser FMTONLY OFF, car les procédures stockées prennent du temps à charger, ce qui entraîne un délai d'attente de génération. J'utilise SQL Server/SSIS 2014.

Merci d'avance!

Marvin

+0

Avez-vous essayé d'autres moyens en dehors des tables temporaires, telles que les tables temporaires globales ou les variables de table? Est-il possible de créer simplement la table temporaire en tant que table normale dans un environnement intermédiaire? – iamdave

+0

Je l'ai considéré, mais ce n'est pas vraiment une option. J'essaie de charger une table de faits (complexe) qui nécessite des étapes intermédiaires (tables temporaires) pour bien fonctionner. La création de tables temporaires persistantes ne correspond pas à l'architecture et ne devrait pas être nécessaire car une chose étrange est, la requête fonctionne quand je la colle dans une source OLE_DB, elle ne fonctionne tout simplement pas lorsque j'essaie de la générer. Je pense que c'est une chose de validation BIML.Peut-être que le moteur utilise encore la validation SSIS2008 ou quelque chose comme ça. À partir de 2012, les SET RESULT devraient fonctionner parfaitement –

+0

J'ai ajouté SET FMTONLY OFF à ma procédure stockée avec un cte. qui est appelée avec la syntaxe des ensembles de résultats. – Doc

Répondre

0

Je suis tombé sur un problème similaire quelque chose de similaire dans mon projet actuel BIML. Le problème, comme vous l'avez mentionné, semble être que Biml ne tient pas compte de la génération de la table temporaire dans une procédure stockée.

Ma solution (solution de contournement?) Consistait à les rendre d'abord des tables temporaires globales, au lieu de simplement des tables temporaires. Ensuite, j'ai créé une nouvelle procédure stockée qui a exécuté le même code que ma procédure stockée principale pour gérer la création de la table temporaire. Avant d'exécuter 'Generate Packages' dans Biml, j'ouvre une nouvelle fenêtre de requête dans SSMS, exécute cette procédure stockée et garde cette fenêtre ouverte (les tables Global Temp durent tant que la session est ouverte). C'est un peu pénible, mais en même temps, cela réduit le temps d'exécution de ma procédure stockée de 35 minutes à 5 minutes et je n'ai qu'à m'inquiéter à ce sujet lors de l'étape 'Generate Packages', donc je Je dirais que ça en valait la peine.

1

J'ai rencontré ces problèmes moi-même auparavant. J'ai utilisé la solution décrite here. La réponse originale n'est pas sur la génération avec BIML mais je l'ai utilisé avec succès cette solution avec BIML Express à Visual Studio 2015.

J'ai utilisé cette procédure stockée comme exemple:

CREATE PROCEDURE csp_MyCsp 
AS 
BEGIN 

    SET NOCOUNT ON; 

    IF 1 = 0 
    BEGIN 
     SELECT CONVERT(INT, NULL) AS [database_id] 
     ,  CONVERT(SYSNAME, NULL) AS [name] 
    END; 

    CREATE TABLE #mydatabases (
     [database_id] INT, 
     [name] SYSNAME 
    ); 

    INSERT INTO #mydatabases 
    SELECT [database_id], [name] 
    FROM sys.databases 

    SELECT [database_id], [name] 
    FROM #mydatabases 

END; 

Et cela a été inclus dans mon BIML :

EXEC dbo.csp_MyCsp WITH RESULT SETS (
    (
     [database_id] INT, 
     [database_name] SYSNAME 
    ) 
)