web-dev-qa-db-fra.com

Requête source OLEDB paramétrée

Je crée un ETL dans SSIS dans lequel je souhaite que ma source de données soit une requête restreinte, comme select * from table_name where id='Variable'. Cette variable est ce que j'ai défini comme variable créée par l'utilisateur.

Je ne comprends pas comment je peux avoir ma requête source interagir avec la variable de portée SSIS.

Les seules options actuelles sont

  • Table
  • Tableau de variable
  • Commande SQL
  • Commande SQL à partir d'une variable

Ce que je veux, c'est avoir une instruction SQL ayant une variable comme paramètre

13
user1765876

Facile. Choisissez SQL command comme mode d'accès aux données. Entrez votre requête avec un point d'interrogation comme espace réservé aux paramètres. Cliquez ensuite sur le bouton Parameters et mappez votre variable sur Parameter0 dans le Set Query Parameters boîte de dialogue:

enter image description here

Plus d'informations sont disponibles sur MSDN .

25
Edmund Schweppe

Une alternative inférieure à l'approche de @ Edmund est d'utiliser une expression sur une autre variable pour construire votre chaîne. En supposant que vous avez déjà défini [@ User :: FirstName], vous créeriez alors une autre variable, @ [User :: SourceQuery].

Dans les propriétés de cette variable, définissez EvaluateAsExpression sur True, puis définissez une expression comme "SELECT FirstName, LastName, FROM Person.Person WHERE FirstName = '" + @[User::FirstName] +"'" Les guillemets doubles sont obligatoires car nous construisons une chaîne SSIS.

Il y a deux grandes raisons pour lesquelles cette approche ne doit pas être implorée.

Mise en cache

Cette approche va gonfler le cache de votre plan dans SQL Server avec N copies essentiellement de la même requête. La première fois qu'il s'exécute et que la valeur est "Edmund", SQL Server créera un plan d'exécution et l'enregistrera (car sa construction peut coûter cher). Vous exécutez ensuite le package et la valeur est "Bill". SQL Server vérifie s'il a un plan pour cela. Ce n'est pas le cas, il n'en a qu'un pour Edmund et il crée donc une autre copie du plan, cette fois codée en dur pour Bill. Faites mousser-rincez-répétez et regardez votre mémoire disponible diminuer jusqu'à ce qu'elle décharge certains plans.

En utilisant l'approche par paramètres, lorsque le plan est soumis à SQL Server, il doit créer une version paramétrée du plan en interne et suppose que tous les paramètres fournis entraîneront des exécutions de coûts égales. De manière générale, c'est le comportement souhaité.

Si votre base de données est optimisée pour une charge de travail ad hoc (c'est un paramètre désactivé par défaut), cela devrait être atténué car chaque plan va être paramétré.

Injection SQL

L'autre gros problème que vous rencontrerez avec la création de votre propre chaîne est que vous vous ouvrez aux attaques par injection SQL ou, au moins, vous pouvez obtenir des erreurs d'exécution. C'est aussi simple que d'avoir une valeur de "d'Artagnan". Ce devis unique entraînera l'échec de votre requête, ce qui entraînera l'échec du package. Changer la valeur en "'; DROP TABLE Person.Person; -" entraînera une grande douleur.

Vous pourriez penser qu'il est trivial de tout citer en toute sécurité, mais l'effort de le mettre en œuvre de manière cohérente partout où vous interrogez va au-delà de ce que votre employeur vous paie. D'autant plus qu'il existe des fonctionnalités natives prévues pour faire la même chose.

10
billinkc

Lorsque vous utilisez le gestionnaire de connexions OLEDB (avec le fournisseur SQL Server Native Client 11.0 dans mon cas), vous pouvez intercepter une erreur comme celle-ci:

Les paramètres ne peuvent pas être extraits de la commande SQL. Le fournisseur peut ne pas aider à analyser les informations de paramètre à partir de la commande. Dans ce cas, utilisez le mode d'accès "Commande SQL à partir d'une variable", dans lequel la commande SQL entière est stockée dans une variable.

Vous devez donc spécifier explicitement le nom de la base de données dans les propriétés du gestionnaire de connexions OLEDB. Sinon, SQL Server Native Client peut utiliser un nom de base de données différent de ce que vous voulez dire (par exemple, maître dans MSSQL Server). Dans certains cas, vous pouvez spécifier explicitement le nom de la base de données pour chaque objet de base de données utilisé dans la requête, par exemple:

select Name
from MyDatabase.MySchema.MyTable
where id = ?
1
iliyesku