0

如何从 CakePHP 正确生成此语句?

DELETE FROM table as Table WHERE Table.expire < NOW();

我已经尝试过了,但这不起作用:

$this->deleteAll(array(
    'Table.expire <' => $this->getDataSource()->expression('NOW()')
));

//It complains:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Table.expire <' in 'where clause'

SQL Query: 
SELECT `Table`.`id` FROM `database`.`table` AS `Table`   WHERE `Table.expire <` = NOW()

现在使它工作的唯一方法是将整个条件作为字符串:

$this->deleteAll('Table.expire < NOW()');
:: OR ::
$this->deleteAll(array('Table.expire < NOW()'));
4

2 回答 2

1

试试这个

$this->delete("all", array('conditions'=>array(
    'Table.expire < ' => $this->getDataSource()->expression('NOW()')))
    );
于 2013-03-22T07:59:35.953 回答
1

我已经测试了你的情况,因为我有点惊讶 CakePHP 没有正确地“引用”

Table.expire <

`Table`.`expire` <

(它通常会这样做)。

可能$this->getDataSource()->expression('NOW()')Returns a stdObjectwith 'NOW()' as a 'value' 属性有关。也许这是 CakePHP 逻辑中的一个“特殊”情况,我不太确定。

数组表示法假定“文字”值,而不是“表达式”

无论如何,一般来说,“数组表示法”会将传递的值视为“文字”值,而不是表达式,因此引用它,例如

'conditions' => array('Table.expire <' => 'some value')
'conditions' => array('Table.expire < ?' => 'another value')
'conditions' => array('Table.expire <' => 'NOW()')

都将被视为'literal'值,从而产生这些SQL条件;

WHERE `Table`.`expire` < 'some value'
WHERE `Table`.`expire` < 'another value'
WHERE `Table`.`expire` < 'NOW()'

因此,这些值被视为字符串,数据库不会将“NOW()”视为“当前日期/时间”。

选项

这将为您提供一些选择;

将条件指定为字符串,而不是键/值数组

您已经在问题中提供了此选项:

'conditions' => array('Table.expire < NOW()')

此解决方案在您的情况下应该是安全的(语句中不包含用户输入),但是,如果用户输入将包含在此类语句中,则应该对其进行适当的清理。此外,NOW()可能不是有效的跨数据库(ANSI SQLCURRENT_TIMESTAMP用于当前日期/时间)

将当前日期/时间指定为 ISO 日期,而不是“表达式”

这是我通常使用的方法;如果您更喜欢数组表示法,您可以考虑为条件提供“文字”日期,最好是 ISO 日期,大多数数据库都可以正确处理该日期;

'conditions' => array('Table.expire <' => date('Y-m-d H:i:s'))

// or

'conditions' => array('Table.expire < ?' => date('Y-m-d H:i:s'))

请注意,我创建了所有示例以用作 a 的“条件”键find(),但是,这同样适用于 adeleteAll()

希望这可以帮助!

于 2013-03-22T21:17:16.187 回答