Sql server 为什么codeigniter数据库缓存会重新生成文件?

Sql server 为什么codeigniter数据库缓存会重新生成文件?,sql-server,database,codeigniter,caching,stored-procedures,Sql Server,Database,Codeigniter,Caching,Stored Procedures,我使用Codeigniter数据库缓存已经有一段时间了,它工作得很好,但现在我在一个特定的查询中遇到了一个奇怪的问题。步骤如下: // Is query caching enabled? If the query is a "read type" // we will load the caching class and return the previously // cached query if it exists if ($this->cache_on =

我使用Codeigniter数据库缓存已经有一段时间了,它工作得很好,但现在我在一个特定的查询中遇到了一个奇怪的问题。步骤如下:

// Is query caching enabled?  If the query is a "read type"
    // we will load the caching class and return the previously
    // cached query if it exists
    if ($this->cache_on == TRUE AND (stristr($sql, 'SELECT')))
    {
        if ($this->_cache_init())
        {
            $this->load_rdriver();
            if (FALSE !== ($cache = $this->CACHE->read($sql)))
            {
                return $cache;
            }
        }
    }
我的缓存目录为空。 我打开URL/myproject/mycontroller/myaction/ 该文件缓存在mycontroller myaction目录中。我用记事本打开该文件,以确保它包含正确的数据。 我再次打开/myproject/mycontroller/myaction/期望从缓存中检索数据,结果发现数据是从数据库中检索的,并且文件y已重新生成。我不知道为什么,但关键是生成的文件是无用的。 如果对您很重要,我将向您提供以下信息:

查询是一个存储过程。 我还有一些其他的问题可以很好地解决。 我非常感谢你的帮助,如果你需要具体的数据,请告诉我

谢谢

使用xdebug,我发现在查询函数中的DB_driver.php文件中,第277行中有一个条件,如下所示:

// Is query caching enabled?  If the query is a "read type"
    // we will load the caching class and return the previously
    // cached query if it exists
    if ($this->cache_on == TRUE AND (stristr($sql, 'SELECT')))
    {
        if ($this->_cache_init())
        {
            $this->load_rdriver();
            if (FALSE !== ($cache = $this->CACHE->read($sql)))
            {
                return $cache;
            }
        }
    }
其中,查询必须是SELECT,我使用的是存储过程,我的模型是:

public function cobertura($param1= NULL) {
        $query = $this->db->query("[SP_NAME] ?", array($param1));
    }

    return $query->result();
}
因此,当我使用存储过程而不是SELECT语句时,该条件返回FALSE并再次生成缓存文件

如何修改该函数以将存储过程检测为有效语句


非常感谢。

这个问题的解决办法是修改这个

if ($this->cache_on == TRUE AND (stristr($sql, 'SELECT')))
由此

if ($this->cache_on == TRUE AND (stristr($sql, 'SELECT') OR strpos($sql, '[')))
这样,我告诉CI,当我的sql语句以[开头时,也是一个SELECT查询

当我有一个不是select语句的存储过程时,只需禁用缓存


如果您有更好的解决方案,您可以与他人共享。

您不应该使用CodeIgniter中的查询缓存。除非您确切知道自己在做什么,否则使用它是不安全的

相反,我会创建一个cacheQuery函数或类似的函数,至少让您可以控制查询的缓存。任何返回数据或可能返回数据的查询都可以缓存的假设是非常危险的

通过替换CI尝试的自动化并手动执行,您也将获得一定的速度。如果您使用xdebug配置文件,那么CI对您的查询所做的所有猜测都会给查询功能增加大量开销

上面发布的解决方案也可能有点不可靠,因为并非所有存储过程都返回数据,方括号可能位于查询中的任何位置,因此check可能会出错。如果第一个字符是false,则返回false;如果该字符位于查询中的任何位置,则返回true,即使它不构成存储过程。例如e、 从表1中删除,其中第1列=[xxx]


这类东西包括str$sql、'SELECT'和strpos$sql、'['不好。CodeIgniter简单、整洁、一致且组织良好,但实际上其中PHP代码的质量非常差。公平地说,部分原因是它保持了与旧版本PHP的兼容性,但有几件事情令人费解地不好。谈到这类事情,CodeIgniter策略s如果90%或更多的时间都能正常工作,那就没问题。这当然不适合大型严肃的企业应用程序。

嗨,你能在控制器上发布代码吗?@PinoyPal,我添加了有用的信息,谢谢你的时间。