我正在尝试在mysql中构建一个参数视图,以便我可以从PHP指定参数调用它。
实际上有两种视图:第一个实现参数,第二个视图仅从第一个视图中进行选择:
CREATE VIEW first_view AS
SELECT * FROM my_table t WHERE t.parameter < get_parameter();
CREATE VIEW second_view AS
SELECT * FROM first_view;
get_parameter
函数的实现方式如下:
CREATE FUNCTION get_parameter() RETURNS timestamp
NO SQL
DETERMINISTIC
BEGIN
IF ISNULL(@parameter) THEN
RETURN DATE(CURDATE()- INTERVAL DAYOFYEAR(CURDATE()) DAY);
ELSE
RETURN @parameter;
END IF;
END
然后,我的查询如下所示:
SELECT v.* FROM (select @parameter := '2014-12-31' p) par, first_view v
这种查询允许我指定参数,然后从first_view
中选择所有内容。
当我在Mysql Workbench上运行这样的查询时,一切都按预期工作,而当我通过PHP运行它时,它返回一个空集。
我在工作台和 PHP 上使用相同的 mysql 用户,所以这不应该是一个任务前问题。
如何也使用 PHP 获取结果集?
更新
我一直在Mysql CLI客户端上尝试这样做,它像PHP一样返回一个空集。
它看起来像查询:
SELECT v.* FROM (select @parameter := '2014-12-31' p) par, first_view v
实际上并没有设置 @parameter
变量,或者至少不是第一次。
事实上,如果我运行查询两次,那么它就可以工作,并且视图返回预期的内容。我通过从 php 向 mysql 发送两个语句来解决这个问题:
首先我设置参数:
SET @parameter = '2014-12-31';
我运行实际查询:
SELECT * FROM second_view;
现在我想知道:为什么第一个查询没有正确实例化参数?
来自 mysql 参考:
如果例程总是产生相同的结果,则被认为是"确定性的" 相同输入参数的结果
您的函数没有输入参数,但会考虑在函数外部声明的变量。
来自 mysql 参考:
将非确定性例程声明为确定性可能会导致 导致优化程序出错的意外结果 执行计划选择。
这只是猜测:但它在 MySQL 工作台而不是 CLI/PHP 中工作的原因可能是工作台会话中的查询缓存可能默认禁用。
您可以尝试验证这一点,以便在 CLI 查询期间禁用缓存:
SELECT SQL_NO_CACHE v.* FROM (select @parameter := '2014-12-31' p) par, first_view v