【问题标题】:Why does stored procedure invalidate SQL Cache Dependency?为什么存储过程会使 SQL 缓存依赖关系失效?
【发布时间】:2010-07-13 06:37:41
【问题描述】:

几个小时后,我终于意识到我可以在 ASP.NET 应用程序中正确使用 Cache 对象,但是我的存储过程阻止它正常工作。

这个存储过程可以正常工作:

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 生成的列 Row 只是临时的事实有关,因此 SQL SERVER 无法说出结果是否更改。这就是 HasChanged 始终设置为 true 的原因。

有人知道如何在不使用 COUNT 或 ROW_NUMBER 函数的情况下对 SQL SERVER 的结果进行分页吗?

【问题讨论】:

    标签: stored-procedures caching sqlcachedependency cache-dependency


    【解决方案1】:

    没有足够的缓存大小。

    【讨论】:

    • 只有 2 个非常小的缓存元素,这是绝对不可能的,但感谢您的尝试。
    • 为什么我这么认为是它看起来像缓存冲突,这意味着缓存在查询期间总是被更新,比如在第二种情况下,存储(即硬盘)和缓存之间的数据交换过多。所以我认为扩大缓存有效。
    • 我觉得这样解决这个问题还是挺难的,但是你能告诉我怎么放大吗?
    【解决方案2】:

    .NET 3.5 的 Sql 缓存依赖项仅适用于简单查询。也许 .NET 4 会让我大吃一惊。

    【讨论】:

      【解决方案3】:

      1 - 您可以复制并粘贴您实际用于缓存该存储过程结果的代码吗? 2 - 您是否尝试过使用直接查询而不是执行字符串的存储过程?

      是的 #2 意味着您不能即时更改查询的结构 :-) 但除非您在 #1 中计算自己的缓存标准,否则您通常必须遵守缓存规则。没有缓存机制会从您那里解析来自 EXEC 的字符串。

      在 sproc 中执行字符串会使该 sproc 在每次运行时都抛硬币,即使对于 SQL Server 本身也是如此。它还使您容易受到脚本注入攻击,因为您的查询在运行时仍然由字符串组成 - 这与在 C# 中组成整个字符串并将其传递给 sproc 以“只执行内部的任何内容”没有任何不同

      【讨论】:

      • @zb_z,我不记得我以哪种形式尝试了存储过程。我很快就会回到应用程序的那个部分,也许会使用 .NET 4 并看看我是如何做到的。那我把代码贴出来让你看看。
      • 既然你试图确定一个问题,最好使用你已经知道和信任的框架版本。有可能使用直接的 sproc(没有带字符串的执行程序)它可能会开始工作。顺便说一句,您不需要实际的 Web 服务器来使用具有依赖项归档的“Web 缓存”类。它们是具有线程安全哈希表且没有 IIS 关联的完全正常的类。哦,还有一件事要记住——依赖条件评估总是懒惰的——只有当有人真正要求对象时才会检查。在这种特殊情况下可能会或可能不会影响您。
      猜你喜欢
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多