2012-05-17 96 views
10

使用SQL我有下面的代碼從數據庫Yii的 - 如何打印通過的findAll

$criteria = new CDbCriteria(); 
    $criteria->condition = 't.date BETWEEN "'.$from_date.'" AND "'.$to_date.'"'; 
    $criteria->with = array('order'); 

    $orders = ProductOrder::model()->findAll($criteria); 

是否有可能得到所使用的的findAll的SQL獲得一些唱片嗎?我知道你可以從調試控制檯得到它。但我在後臺運行腳本使用yiic.php

回答

16

您可以將執行的查詢記錄在應用程序日誌中並查看該腳本。像這樣的事情在配置文件:

'components' => array(
    'db'=>array(
    'enableParamLogging' => true, 
), 
    'log'=>array(
    'class'=>'CLogRouter', 
    'routes'=>array( 
     array(
     'class'=>'CFileLogRoute', 
     'levels'=>'trace,log', 
     'categories' => 'system.db.CDbCommand', 
     'logFile' => 'db.log', 
    ), 
    ), 
), 
); 

在某些情況下(例如運行測試時),你還需要調用Yii::app()->log->processLogs(null);在過程結束這個工作。

當然,一旦你在那裏沒有任何東西阻止你編寫自己的日誌路由,它會在日誌消息中做一些不同的事情,但是請注意日誌在請求結束時處理(或者當您致電processLogs時) ,不是每次你記錄一些東西。


順便說一句,你不應該直接在查詢建立這樣的查詢,動態輸入。使用綁定變量來代替:

$criteria = new CDbCriteria(); 
$criteria->condition = 't.date BETWEEN :from_date AND :to_date'; 
$criteria->params = array(
    ':from_date' => $from_date, 
    ':to_date' => $to_date, 
); 
$criteria->with = array('order'); 

$orders = ProductOrder::model()->findAll($criteria); 
+0

似乎沒有直接sql命令的DAO比使用CDbcriteria更簡單/更快? – itachi

+3

取決於你想對結果做什麼,我想。如果你想使用模型功能(例如驗證),使用AR是一個明顯的選擇。就個人而言,我更喜歡AR,並且只對更復雜的情況(如涉及加入的更新)留下DAO。這樣,我可以將模型範圍用於常見條件,並且在架構或業務邏輯更改時不必手動審查/更新所有直接命令。 (另外,在任何地方使用AR都意味着訪問結果中包含的數據的一致方式,而不必擔心結果行是對象還是數組......) – DCoder

+0

明白了您的觀點。 thanx的解釋。 – itachi

1

您可以直接看到頁面上登錄:

'log'=>array(
    'class'=>'CLogRouter', 
    'routes'=>array(
     array(
      'class'=>'CWebLogRoute', 
     ), 
    ), 
), 
4

您可以通過使用CDbCommandBuilder獲得SQL,像這樣:

ModelClassName::model()-> getCommandBuilder()-> createFindCommand('tableName', $criteria)->text;

+1

這是簡單查詢的一個很好的解決方案,但它[不考慮「with」](https://github.com/yiisoft/yii/blob/1.1.16/framework/db/schema/CDbCommandBuilder.php#L74 )這是在OP的例子中陳述 – Motin

0

如果您不希望在查看SQL之前執行查詢,這實際上並不像您希望的那樣容易。

它和錯誤一樣髒,但是在開發過程中,我過去習慣於在標準中添加故意的故意錯誤,並依靠生成的異常來嘗試SQL。

例如

$criteria = new CDbCriteria(); 
$criteria->condition = 't.date_fgjhfgjfgj BETWEEN :from_date AND :to_date'; 
$criteria->params = array(
    ':from_date' => $from_date, 
    ':to_date' => $to_date, 
); 
$criteria->with = array('order'); 
$orders = ProductOrder::model()->findAll($criteria); 

我發現伊利亞的方法是不可靠的(不知道爲什麼,但有時準則採用這種方法忽略)。

5
  • 第一種方式(官方途徑):
    在你main.php配置文件在您添加log section這兩個參數,你可以看到在您的網頁或在瀏覽器FireBug Console結束日誌消息。不要忘記在db部分設置必要的參數。

    'components' => array( 'db'=>array( 'enableProfiling'=>true, 'enableParamLogging' => true, ), 'log'=>array( 'class'=>'CLogRouter', 'routes'=>array( array( 'class'=>'CWebLogRoute', 'showInFireBug' => true, ), array( 'class'=>'CProfileLogRoute', 'levels'=>'profile', 'enabled'=>true, ), ), ), );

  • 方式二:
    在你的代碼只是改變你的一列的拼寫不正確的數據,你會得到一個錯誤消息包含在你的錯誤頁面完整的SQL查詢(你應該在YII_DEBUG模式下爲真)。是這樣的:
    (我已經改變t.datet.wrong_date,當你刷新頁面,你會看到這是在數據庫中執行生成的SQL)

$criteria = new CDbCriteria(); $criteria->condition = 't.wrong_date BETWEEN "'.$from_date.'" AND "'.$to_date.'"'; $criteria->with = array('order'); $orders = ProductOrder::model()->findAll($criteria);

在這兩種方式中,都有YII_DEBUG true index.php

defined('YII_DEBUG') or define('YII_DEBUG',true); 
+1

我總是使用第二個 – Xcoder