2009-08-04 63 views
2

如果我想這樣做(注意期滿線):如何通過Doctrine將字面參數發送到數據庫?

$duration=24; //in hours 

$reset=new PasswordReset(); 
$reset->code=md5(uniqid()); 
$reset->expires="now() + interval $duration hours"; 
$reset->User=$user; 
$reset->save(); 

我怎樣才能教到其發送到PostgreSQL之前,請不要引用呢?我知道我可以在PHP中做到這一點,但我想知道以供將來參考。

回答

1

你可能想看看Using Expression Values

給出的例子是這樣的(引述DOC)

$user = new User(); 
$user->username = 'jwage'; 
$user->updated_at = new Doctrine_Expression('NOW()'); 
$user->save(); 

,並生成該SQL查詢:

INSERT INTO user (username, updated_at_) VALUES ('jwage', NOW()) 

我假設它會這樣做,在你的情況?
(我沒有啓用學說項目就在這裏,所以不能測試你)


一點題外話:我沒有PostgreSQL服務器上測試;但是你提出關於MySQL不工作是什麼:看來你必須使用「now() + interval 2 hour」,而不是「now() + interval 2 hours」 - 不過,我不知道PG評論後


編輯

呃,你說得對,這不是一個正確的解決辦法;這是行不通的:-(

嗯......有趣的問題,所以我挖多一點,就去主義的源代碼,我想我可能發現一些有趣的事情

如果。你看看Doctrine_Query_Where::parseValue源的來源,你會發現這個代碼部分:

// If custom sql for custom subquery 
// You can specify SQL: followed by any valid sql expression 
// FROM User u WHERE u.id = SQL:(select id from user where id = 1) 
} elseif (substr($trimmed, 0, 4) == 'SQL:') { 
    $rightExpr = '(' . substr($trimmed, 4) . ')'; 
// simple in expression found 

我已經是絕對沒有試過,但是這可能是有趣......

也許你可以做這樣的事情:

$reset->expires="SQL:(now() + interval $duration hours)"; 

如果你這樣做,我很感興趣,知道它是否會工作!
可能是有用的,一天或其他;-)

順便說一句,似乎它在Doctrine_Search太習慣;看看這一個,也許它會工作沒有括號,如下所示:

$reset->expires="SQL:now() + interval $duration hours"; 

嗯......我希望,這一次,它幫助...因爲我看不出有其他辦法可以做到你想之後的第二(第三獲取(和谷歌並不能幫助我要麼^^)


編輯什麼,如果算上礦)評論。
我會得到這個工作......不然,我就沒有睡好^^

好吧,我可能已經找到了一種方法(和,這一次,我測試了^^);不是真的一樣大,一想,但是,反正更新時,它似乎是工作...

比方說,我有一個表創建這樣:

CREATE TABLE `test1`.`test` (
    `id` int(11) NOT NULL auto_increment, 
    `name` varchar(32) NOT NULL, 
    `value` varchar(128) NOT NULL, 
    `date_field` datetime NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

相應的模型類是什麼樣子這樣的:
也許並不完美:它是一個測試類,我別的東西寫的,我已經突變,以適應這一^^

class Test extends Doctrine_Record 
{ 
    public function setTableDefinition() 
    { 
     $this->setTableName('test'); 
     $this->hasColumn('id', 'integer', 4, array(
      'type' => 'integer', 
      'length' => 4, 
      'unsigned' => 0, 
      'primary' => true, 
      'autoincrement' => true, 
      )); 
     $this->hasColumn('name', 'string', 32, array(
      'type' => 'string', 
      'length' => 32, 
      'fixed' => false, 
      'notnull' => true, 
      )); 
     $this->hasColumn('value', 'string', 128, array(
      'type' => 'string', 
      'length' => 128, 
      'fixed' => false, 
      'primary' => false, 
      'notnull' => true, 
      'autoincrement' => false, 
      )); 
     $this->hasColumn('date_field', 'integer', 4, array(
      'type' => 'timestamp', 
      'notnull' => true, 
      )); 
    } 
} 

我將插入兩行到該表:

$test = new Test(); 
$test->name = 'Test 1'; 
$test->value = 'My Value 1'; 
$test->date_field = "2009-01-30 08:30:00"; 
$test->save(); 

$test = new Test(); 
$test->name = 'Test 2'; 
$test->value = 'My Value 2'; 
$test->date_field = "2009-02-05 08:30:00"; 
$test->save(); 

這讓我從SQL這樣的數據:
BTW:我沒有PG服務器,所以我將測試與MySQL一切 - 應該在PG工作過,還是......

mysql> select * from test; 
+----+--------+------------+---------------------+ 
| id | name | value  | date_field   | 
+----+--------+------------+---------------------+ 
| 1 | Test 1 | My Value 1 | 2009-01-30 08:30:00 | 
| 2 | Test 2 | My Value 2 | 2009-02-05 08:30:00 | 
+----+--------+------------+---------------------+ 
2 rows in set (0.00 sec) 

因此,兩條線,與日期很久以前在過去。


現在,可以肯定,我們只取線#1:

$testBefore = Doctrine::getTable('Test')->find(1); 
var_dump($testBefore->toArray()); 

我得到這樣的輸出:

array 
    'id' => string '1' (length=1) 
    'name' => string 'Test 1' (length=6) 
    'value' => string 'My Value 1' (length=10) 
    'date_field' => string '2009-01-30 08:30:00' (length=19) 


而且,目前,有趣的部分:讓我們更新該行,使用類似於您提供的表達式來設置date_field值:

$query = new Doctrine_Query(); 

$query->update('test') 
    ->set('date_field', 'NOW() - interval 2 hour') 
    ->where('id = ?', 1) 
    ->execute(); 

var_dump($query->getSql()); 

的SQL,我得到的作爲輸出是這一個:

string 'UPDATE test SET date_field = NOW() - interval 2 hour WHERE id = ?' (length=65) 

這有點像你想要什麼,如果我沒有記錯;-)


而且,只是可以肯定,讓我們再一次抓取我們的產品線:

$testAfter = Doctrine::getTable('Test')->find(1); 
var_dump($testAfter->toArray()); 

我得到這樣的結果:

array 
    'id' => string '1' (length=1) 
    'name' => string 'Test 1' (length=6) 
    'value' => string 'My Value 1' (length=10) 
    'date_field' => string '2009-08-04 21:26:30' (length=19) 

考慮的日期和時間,看來這個工作 - hoorray!

而且,可以肯定的,讓我們直接從數據庫中查詢數據:

mysql> select * from test; 
+----+--------+------------+---------------------+ 
| id | name | value  | date_field   | 
+----+--------+------------+---------------------+ 
| 1 | Test 1 | My Value 1 | 2009-08-04 21:26:30 | 
| 2 | Test 2 | My Value 2 | 2009-02-05 08:30:00 | 
+----+--------+------------+---------------------+ 
2 rows in set (0.00 sec) 

而且...... Yeeeepe!


好了,現在,不那麼好的部分:要能使用的語法,我不得不創建查詢「手動」,與「漂亮」使用set()方法,而不是做模型類和save()方法:-(

現在,就由你來看看你,可以集成到你的模型類的...有與;-)

樂趣,如果你找到一種方法,有一天,要在查詢的其他部分使用像這樣的表達式,或者使用更簡潔的方式,我非常感謝您是否可以發表評論以讓我知道;-)


而且,這個時間,我衷心希望我找到的方式^^

+0

看起來Doctrine_Expression是使用SQL函數學說可以轉換成便攜的表達。在這種情況下它不起作用。 – ryeguy 2009-08-04 18:52:47

+0

Ergh :-(我用另一個想法編輯了我的答案......但是,如果這個也不起作用,恐怕沒有多少希望:-( – 2009-08-04 19:14:32

+0

感謝您的挖掘,但它看起來像教義只有在where子句中才會查找「SQL:」。似乎並不在乎設置值時是否會這樣做,儘管如此,我還是努力+1,我很欣賞它 – ryeguy 2009-08-04 20:48:41

相關問題