Почему хранимая процедура делает недействительной зависимость от кэша SQL?

StackOverflow https://stackoverflow.com/questions/1553735

Вопрос

Спустя много часов я наконец осознаю, что правильно работаю с объектом 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_NUMBER, является временной и, следовательно, SQL SERVER не может сказать, изменились ли результаты или нет.Вот почему HasChanged всегда имеет значение true.

Кто-нибудь знает, как разбивать результаты SQL SERVER на страницы без использования функций COUNT или ROW_NUMBER?

Это было полезно?

Решение 2

Зависимость кэша Sql для .NET 3.5 работает только для простых запросов.Возможно, .NET 4 меня удивит.

Другие советы

недостаточно размера кэша.

1. Можете ли вы скопировать и вставить код, который вы фактически используете для кэширования результатов этой процедуры?2. Пробовали ли вы процедуру, в которой вы используете прямой запрос вместо выполнения строки EXEC?

Да, № 2 означает, что вы не можете изменить структуру запроса на лету :-) но если вы не рассчитываете свои собственные критерии кэширования в № 1, это правило кэширования, которое вы должны соблюдать в целом.Ни один механизм кэширования никогда не сможет проанализировать строку из EXEC от вас.

Выполнение EXEC строки в процедуре превращает эту процедуру в сплошное подбрасывание монеты при каждом запуске даже для самого SQL Server.Это также оставляет вас открытым для атак путем внедрения скриптов, поскольку ваш запрос по-прежнему состоит из строк во время выполнения - это ничем не отличается от составления всей строки в C # и передачи ее в sproc для «просто EXEC того, что находится внутри».

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top