Почему хранимая процедура делает недействительной зависимость SQL Cache?
Через много часов я наконец понимаю, что правильно работаю с объектом Cache в своем приложении ASP.NET, но мои хранимые процедуры мешают ему работать правильно.
Эта хранимая процедура работает правильно:
CREATE PROCEDURE [dbo].[ListLanguages]
@Page INT = 1,
@ItemsPerPage INT = 10,
@OrderBy NVARCHAR (100) = 'ID',
@OrderDirection NVARCHAR(4) = 'DESC'
AS
BEGIN
SELECT ID, [Name], Flag, IsDefault FROM dbo.Languages
END
Но это (то, что я хотел) не:
CREATE PROCEDURE [dbo].[ListLanguages]
@Page INT = 1,
@ItemsPerPage INT = 10,
@OrderBy NVARCHAR (100) = 'ID',
@OrderDirection NVARCHAR(4) = 'DESC',
@TotalRecords INT OUTPUT
AS
BEGIN
SET @TotalRecords = 10
EXEC('SELECT ID, Name, Flag, IsDefault FROM (
SELECT ROW_NUMBER() OVER (ORDER BY ' + @OrderBy + ' ' + @OrderDirection + ') as Row, ID, Name, Flag, IsDefault
FROM dbo.Languages) results
WHERE Row BETWEEN ((' + @Page + '-1)*' + @ItemsPerPage + '+1) AND (' + @Page + '*' + @ItemsPerPage + ')')
END
Я дал параметру @TotalRecords значение 10, чтобы вы могли быть уверены, что проблема не в функции COUNT(*), которая, как я знаю, не поддерживается должным образом.
Кроме того, когда я запускаю его из SQL Server Management Studio, он делает именно то, что должен делать. В приложении ASP.NET результаты извлекаются корректно, только кеш как-то не может работать!
Можете ли вы помочь?
Возможно подсказка
Я полагаю, что причина, по которой свойство зависимостей HasChanged связано с тем, что столбец Row, сгенерированный из ROW_NUMBER, является только временным, и поэтому SQL SERVER не может сказать, изменились ли результаты или нет. Вот почему HasChanged всегда имеет значение true.
Кто-нибудь знает, как разбить на страницы результаты из SQL SERVER без использования функций COUNT или ROW_NUMBER?
3 ответа
Зависимость кэша SQL для.NET 3.5 работает только для простых запросов. Может быть.NET 4 меня удивит.
1 - Можете ли вы скопировать и вставить код, который вы фактически используете для кэширования результатов этого спрока? 2 - Вы пробовали sproc, где вы используете прямой запрос вместо EXEC-строки?
Да #2 означает, что вы не можете изменить структуру запроса на лету:-), но если вы не вычисляете свои собственные критерии кэширования в #1, это правило кэширования, которое вы должны соблюдать в целом. Ни один механизм кеширования никогда не сможет проанализировать строку из EXEC от вас.
ВЫПОЛНЕНИЕ строки в sproc приводит к тому, что при каждом запуске, даже для самого SQL Server, происходит бросок монеты. Это также оставляет вас открытыми для атак с помощью внедрения скриптов, так как ваш запрос все еще состоит из строк во время выполнения - это ничем не отличается от составления всей строки в C# и передачи ее в sproc для "просто EXEC, что находится внутри"