2010-09-01 3 views
0

Я создал процедуру для одного из наших .Net Devs, где они могут передавать значения, которые затем будут строить и выводить набор результатов. Часть параметров, которые они передают, определит, какая таблица вызывается. Мой вопрос в том, как я могу гарантировать, что динамический SQL-запрос, который я создаю, будет кэшироваться для более быстрого выполнения? Ни один из примеров кэша, которые я прочитал, не обсуждал динамические имена таблиц (возможно, они просто не учитывались), просто динамические параметры в запросе.SQL Server 2008 - Cache Dynamic SQL

Я использую sp_executesql и передаю в params, но я не уверен, как использовать этот метод для получения имени таблицы без добавления параметра в инструкцию select?

Вот простой пример того, как я в настоящее время строю строку для создания моего набора результатов.

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; 

Любая информация с благодарностью.

-S

ответ

3

я настоятельно рекомендовал бы против такого рода «сделать это» процедура. Намного лучше, чтобы ваши разработчики .NET работали в тандеме с администратором баз данных для создания правильных операторов SQL или, по крайней мере, использовали ORM, а не пытались обрабатывать вызовы базы данных таким образом, как вы предложили. Если вы собираетесь заставить своих разработчиков использовать хранимые процедуры, выпишите хранимые процедуры. Это упростит техническое обслуживание и анализ производительности, чем наличие одной хранимой процедуры для их всех.

Как я могу гарантировать, что динамический оператор sql, который я создаю, будет кэшироваться для более быстрого выполнения?

SQL Server должен кэшировать план выполнения двух идентичных запросов. Таким образом, если ваш динамический SQL генерирует два идентичных запроса, SQL Server будет кэшировать план выполнения. То, что он не сделает, - это два запроса, которые должны использовать один и тот же план выполнения, но немного отличаться. Например, если ваш динамический SQL генерирует Select ... From Table Where Col = 1 и Select ... From Table Where Col = 2, SQL Server рассчитает два плана выполнения, даже если эти два значения имеют одинаковую мощность. Это одно место, где параметризованные запросы или статически написанные хранимые процедуры лучше.

Я использую sp_executesql и передаю в params, но я не уверен, как использовать этот метод для получения имени таблицы без добавления параметра в оператор select?

Если вы собираетесь использовать sp_executesql, вам нужно построить весь оператор SQL, включая таблицу в виде строки. Вы не можете передать имя таблицы в качестве параметра.

+0

Спасибо за информацию Томас Я ценю это. – scarpacci

+0

Не говоря уже о том, что при наличии динамического SQL почти всегда есть вероятность для SQL-инъекций. – StingyJack

2

вы не можете кэшировать динамические таблицы имен, другая таблица представляет собой другой план .... так просто

+0

Спасибо SQL Menace – scarpacci

+0

Не то, чтобы в любом случае было бы затруднительно кэшировать тривиальные запросы. – StingyJack