Question

When I execute some query with a $this->query, CakePHP return this:

Model:

<?php
App::uses('AppModel', 'Model');

class Authorization extends AppModel {

    public $displayField = 'name';
    public $useTable = 'auth';
    public $actsAs = array();

SQL in Model:

public function getNotUsed($initialDate, $finalDate)
{

  $sql = "SELECT auth_num ,
               auth_code ,
               amount AS verisign_amount ,
               print_amount ,
               card_name ,
               a.table_num AS table_num ,
               a.add_date AS date ,
               'Tb:'|| table_num || ' - ' || auth_code || ' - $' || print_amount AS code_print_amount
          FROM auth a
          WHERE trxtype = 'S'
            AND gift_card = 'N'
            AND used = 'N'
            AND a.add_date BETWEEN '$initialDate' AND '$finalDate'
            AND pnref NOT IN
              (SELECT origid
               FROM auth a
               WHERE add_date BETWEEN '$initialDate' AND '$finalDate'
                 AND trxtype = 'V')
          ORDER BY add_date";

  return $this->query($sql);

}

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [auth_num] => 536825
                    [auth_code] => 0000000
                    [verisign_amount] => 0.50
                    [print_amount] => 0.50
                    [card_name] => TEST
                    [table_num] => 37
                    [date] => 02/20/2013 14:56:35
                    [code_print_amount] => Tb:37 - 198198 - $0.50
                )

        )

)

I want this (when search more than 1 row):

Array
(
    [0] => Array
        (
            ['Authorization'] => Array
                (
                    [auth_num] => 536825
                    [auth_code] => 0000000
                    [verisign_amount] => 0.50
                    [print_amount] => 0.50
                    [card_name] => TEST
                    [table_num] => 37
                    [date] => 02/20/2013 14:56:35
                    [code_print_amount] => Tb:37 - 198198 - $0.50
                )

        )

)

Or this (when search more 1 row - limit 1):

Array
(
       ['Authorization'] => Array
           (
               [auth_num] => 536825
               [auth_code] => 0000000
               [verisign_amount] => 0.50
               [print_amount] => 0.50
               [card_name] => TEST
               [table_num] => 37
               [date] => 02/20/2013 14:56:35
               [code_print_amount] => Tb:37 - 198198 - $0.50
         )
)



How can I execute this query and get just a first array key (with all fields). In this case, the 2nd array key [0]. Or just a [0] => ['Authorization'] => array().


I'm using:

  • CakePHP 2.3.0
  • PHP 5.3.8
  • Apache 2.2
  • Postgres 8.4

Was it helpful?

Solution

Only use RAW SQL if really nescessary

First of all, try to avoid using RAW SQL queries unless there's really no other option. Also, when using RAW SQL, keep in mind that you will have to sanitize your queries yourself to prevent SQL injection. Since you're dealing with payment information, please double check that you're escaping $initialDate and $finalDate, because I don't see any security measures in your code.

Formatting the results

To get the results the way you want, you'll have to use aliases for your fields in a 'special' format;

SELECT
    myfield      AS "Mymodel__somefield", 
    myotherfield AS "Mymodel__someotherfield"

FROM .....

note there should be two underscores between Mymodel and fieldname

Should return;

array (
    0 => array(
        'Mymodel' => array (
            'somefield' => 'foo',
            'otherfield' => 'bar',
        )
    )
)

OTHER TIPS

So taking @thaJeztah's advice, your query needs to be changed to something like following:

$sql = "SELECT `Authentication`.`auth_num`,
               `Authentication`.`auth_code`,
               `Authentication`.`amount` AS `Authentication`.`verisign_amount`,
               `Authentication`.`print_amount`,
               `Authentication`.`card_name`,
               `Authentication`.`table_num`,
               `Authentication`.`add_date` AS `Authentication`.`date`,
               'Tb:'|| `Authentication`.`table_num` || ' - ' || `Authentication`.`auth_code` || ' - $' || `Authentication`.`print_amount` AS `Authentication`.`code_print_amount`
          FROM `auth` as `Authentication`
          WHERE `Authentication`.`trxtype` = 'S'
            AND `Authentication`.`gift_card` = 'N'
            AND `Authentication`.`used` = 'N'
            AND `Authentication`.`add_date` BETWEEN '?' AND '?'
            AND `Authentication`.`pnref` NOT IN
              (SELECT o`Authentication`.`rigid`
               FROM `auth` as `Authentication`
               WHERE `Authentication`.`add_date` BETWEEN '?' AND '?'
                 AND `Authentication`.`trxtype` = 'V')
          ORDER BY `Authentication`.`add_date`";

I actually took a bit of a chance in guessing which tables stuff came from. It is really important to namespace your fields so you don't leave the database guessing where the fields come from.

Also to echo @theJeztah's answer, try and avoid writing SQL yourself. If you have sub-queries, then try to break them into multiple $this->model->find(...). Its not as quick but its probably far safer.

Your code might be:

$this->query('select * etc');

Show us more code, if this doesn't work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top