2010-09-01 7 views
0

J'ai créé une procédure pour l'un de nos développeurs .Net où ils peuvent transmettre des valeurs qui vont ensuite générer et sortir un ensemble de résultats. Une partie des paramètres qu'ils passent déterminera quelle table sera appelée. Ma question est de savoir comment puis-je m'assurer que l'instruction sql dynamique que je suis en train de créer sera mise en cache pour une exécution plus rapide? Aucun des exemples de cache que j'ai lus ne traitait de noms de tables dynamiques (peut-être juste négligés), seulement des paramètres dynamiques dans la requête.SQL Server 2008 - Cache Dynamic SQL

J'utilise sp_executesql et je passe des paramètres, mais je ne suis pas sûr de savoir comment utiliser cette méthode pour dériver le nom de la table sans ajouter le paramètre à l'instruction select?

Voici un exemple simple de la façon dont je construis actuellement la chaîne pour générer mon jeu de résultats.

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DynamicSQL]') AND type in (N'U')) 
DROP TABLE [dbo].[DynamicSQL] 
GO 

CREATE TABLE [dbo].[DynamicSQL](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [TestName] [varchar](100) NULL 
) ON [PRIMARY] 

GO 

Insert Into DynamicSQL 
Values('Name1'); 
Insert Into DynamicSQL 
Values('Name2'); 
Insert Into DynamicSQL 
Values('Name3'); 
Insert Into DynamicSQL 
Values('Name4'); 

GO 

DECLARE @TableName VARCHAR(50), 
     @SQL  NVARCHAR(500) 

SELECT @TableName = 'DynamicSQL', 
     @SQL = 'Select * 
      From ' + @TableName; 

execute sp_executesql @SQL; 

Toute information est grandement appréciée.

-S-

Répondre

3

Je recommande fortement contre ce genre de procédure « faire ». Il est préférable que vos développeurs .NET travaillent en tandem avec un administrateur de base de données pour créer des instructions SQL correctes ou à tout le moins utilisent un ORM plutôt que d'essayer de gérer les appels de base de données comme vous l'avez suggéré. Si vous voulez forcer vos développeurs à utiliser des procédures stockées, alors écrivez les procédures stockées. Cela rendra l'entretien et l'analyse des performances beaucoup plus faciles que d'avoir un proc stocké pour les gouverner tous. Comment puis-je m'assurer que l'instruction sql dynamique que je construis sera mise en cache pour une exécution plus rapide? SQL Server doit mettre en cache le plan d'exécution de deux requêtes identiques. Ainsi, si votre SQL dynamique génère deux requêtes identiques, SQL Server mettra en cache le plan d'exécution. Ce qu'il ne fera pas, c'est mettre en cache deux requêtes qui devraient utiliser le même plan d'exécution mais qui sont légèrement différentes. Par exemple, si votre SQL dynamique génère Select ... From Table Where Col = 1 et Select ... From Table Where Col = 2, SQL Server calcule deux plans d'exécution même si les deux valeurs ont la même cardinalité. C'est un endroit où les requêtes paramétrées ou les procédures stockées statiquement écrites sont meilleures. J'utilise sp_executesql et passe en params, mais je ne suis pas sûr comment j'utilise cette méthode pour dériver le nom de la table sans ajouter le paramètre à l'instruction select? Si vous comptez utiliser sp_executesql, vous devez générer l'instruction SQL complète, y compris la table sous la forme d'une chaîne. Vous ne pouvez pas passer le nom de la table en tant que paramètre.

+0

Merci pour l'info Thomas je l'apprécie. – scarpacci

+0

Sans compter que lorsqu'il y a du SQL dynamique, il y a presque toujours une chance pour les attaques par injection SQL. – StingyJack

2

vous ne pouvez pas mettre en cache les noms de tables dynamiques, un tableau différent est un plan différent .... aussi simple que cela

+0

Merci SQL Menace – scarpacci

+0

Pas que cela dérange de mettre en cache des requêtes triviales de toute façon. – StingyJack