Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Boa noite pessoal.
Estou enroscado com o foreach.
Abaixo quero fazer uma pesquisa no banco de dados, e os dados que retornarem adicionar em outra tabela como um novo registro.
Na tabela que faço a pesquisa (invoiceitems) existe dois registro (como exemplo), quero que ele pegue esses dois registros e insira na tabela "Transactions".
Porém, da forma que está abaixo ele só está gravando um registro, o outro ele ignora, onde pode estar o erro?
Segue:
$query = "SELECT description,amount, plano_contas, centro_custo from invoiceitems where invoiceid='$rid'"; $stmt = $dbh->prepare("$query"); $stmt->execute(); $result = $stmt->fetchAll(); $i="0"; $ext = EXT; foreach($result as $value) { $memos = $value['description']; $plano = $value['plano_contas']; $cc = $value['centro_custo']; $valoritem = $value['amount']; $tr = ORM::for_table('transactions')->create(); $tr->ttype='Income'; $tr->tfrom=$cid; $tr->tto='102'; $tr->plano_contas=$plano; $tr->centro_custo=$cc; $tr->amount=$valoritem; $tr->date = date('Y-m-d'); $tr->memo=$memos; $tr->status='Completed'; //$i++; }
Só uma observação, na colagem acima esqueci de fechar as chaves... mas a duvida é a mesma..
Entendi.. você poderia me dar um exemplo em cima da minha rotina?
Comente o $result = $stmt->fetchAll(); (comentar é colocar // na frente), remova o foreach e no lugar use:
while($value = $stmt->fetch(PDO::FETCH_ASSOC)){
Ainda não deu certo.
Ele continua pegando somente uma linha do banco de dados, me parece que ele não está fazendo o looping.
No banco de dados está tudo ok, existe 2 registros com o id, mas ele lê somente um e grava na outra tabela.
segue o código abaixo como me passou:
$query = "SELECT description,amount, plano_contas, centro_custo from invoiceitems where invoiceid='$rid'";
$stmt = $dbh->prepare("$query");
$stmt->execute();
// $result = $stmt->fetchAll();
$i="0";
$ext = EXT;
while($value = $stmt->fetch(PDO::FETCH_ASSOC)) {
$memos = $value['description'];
$plano = $value['plano_contas'];
$cc = $value['centro_custo'];
$valoritem = $value['amount'];
$tr = ORM::for_table('transactions')->create();
$tr->ttype='Income';
$tr->tfrom=$cid;
$tr->tto='102';
$tr->plano_contas=$plano;
$tr->centro_custo=$cc;
$tr->amount=$valoritem;
$tr->date = date('Y-m-d');
$tr->memo=$memos;
$tr->status='Completed';
$i++;
}Dá um rowCount nisso e veja o que realmente está retornando, também dá um print_r dentro do laço e veja qual o resultado, poste o script inteiro também vale ressaltar além de tudo, que você deve executar a query que insere os dados no BD dentro do laço, falo isto porque não sei qual o nome do método que executa a query no seu ORM, mas ao que parece não está dentro do código que você passou.
Segue abaixo o codigo por inteiro, vou comentar algumas linhas para você entender melhor.
$rid = _get('_xClick'); // Aqui eu pego o ID do boleto que quero dar baixa, que veio via post $self = 'invoice.php?_show='.$rid; // aqui eu apresento na tela o boleto em questão. $cmd = ORM::for_table('invoices')->find_one($rid); // aqui eu procuro na tabela invoice o registro correspondente ao boleto e faço as primeiras operações de baixa. $cmd->status='Paid'; $cid = $cmd['userid']; $sTotal = $cmd['total']; $cmd->save(); // Aqui eu procuro na tabela filho "Invoiceitems" os item que foram cadastrados no boleto, para que eu possa gravar na tabela "Transactions" onde eu faço meu fluxo de caixa. $query = "SELECT description,amount, plano_contas, centro_custo from invoiceitems where invoiceid='$rid'"; $stmt = $dbh->prepare("$query"); $stmt->execute(); // $result = $stmt->fetchAll(); $i="0"; $ext = EXT; if ($stmt->rowCount() > 0) { foreach($result as $value) { // eu tenho que procurar todos os itens do boleto nesses campos abaixo que está na tabela e gravar o resultado na tabela "transactions" $memos = $value['description']; $plano = $value['plano_contas']; $cc = $value['centro_custo']; $valoritem = $value['amount']; $tr = ORM::for_table('transactions')->create(); $tr->ttype='Income'; $tr->tfrom=$cid; $tr->tto='102'; $tr->plano_contas=$plano; $tr->centro_custo=$cc; $tr->amount=$valoritem; $tr->date = date('Y-m-d'); $tr->memo=$memos; $tr->status='Completed'; $i++; }}
O ORM está correto, mais mesmo assim segue abaixo a logica dele.
Ele chega a gravar, mas somente um registro.
Segue:
/** Despite its slightly odd name, this is actually the factory method used to acquire instances of the class. It is named this way for the sake of a readable interface, ie ORM::for_table('table_name')->find_one()-> etc. As such, this will normally be the first method called in a chain. @param string $table_name @param string $connection_name Which connection to use @return ORM */ public static function for_table($table_name, $connection_name = self::DEFAULT_CONNECTION) { self::_setup_db($connection_name); return new self($table_name, array(), $connection_name); }
Se precisar eu faço outro tipo de conexão,
Só me ajude para algo que funcione para meu problema.
Muito obrigado por enquanto.
Thiago, acredito que estamos pecando em algo muito básico, mas antes disto, vamos nos ater ao básico do básico, o nosso nobre português... se você ler com muita atenção o que eu citei no post #7, vai ver que eu citei um negócio chamado rowCount e também falei de um bichinho chamado print_r, você utilizou eles? Se sim, os dados foram apresentados conforme era esperado?
O meu palpite:
1 - Seu ORM tem algum problema;
2 - A sua query está retornando apenas 1 linha.
A query está voltando no var_dump o resultado de: int(2)
Neste caso ele está achando os dois registros.
O ORM está funcionando certinho...
Mas mesmo assim ele grava somente 1 registro durante o foreach
Estranho..
Eu estou achando que o problema está no Foreach
Enxuguei a rotina para fazer o teste, segue abaixo:
$act = _post('act');
if ($act==''){
$act = _get('_cmd');
}
$rtxt = '';
$rid = _get('_xClick'); // <= aqui eu estou recebendo o numero do boleto da tela anterior
$cmd = ORM::for_table('invoices')->find_one($rid); <= aqui eu estou somente pegando o id filho da tabela pai, e coloco na variavel $cid abaixo e já coloco este boleto como pago na tabela pai (no caso a tabela "invoice")
$cmd->status='Paid';
$cid = $cmd['userid']; //<== esta variavel que eu uso na rotina abaixo...está tudo ok até aqui.
$sTotal = $cmd['total'];
$cmd->save();
// adiconando entrada na tabela filho (invoiceitems)
$query = "SELECT * from invoiceitems where invoiceid='$rid'";
$stmt = $dbh->prepare("$query");
$stmt->execute();
$result = $stmt->fetchAll();
$i="0";
$ext = EXT;
// $teste = $stmt->rowCount();
// var_dump($teste);
// aqui embaixo é para ele encontrar os 2 registros que coloquei na tabela filho "invoiceitems" para teste, porem ele só encontra 1 e faz a gravação, parece que ele não está fazendo o loop para achar o segundo. Na minha tabela consta 2 registro com este id.
foreach($result as $value) {
$memos = $value['description'];
$plano = $value['plano_contas'];
$cc = $value['centro_custo'];
$valoritem = $value['amount'];
$tr = ORM::for_table('transactions')->create();
$tr->ttype='Income';
$tr->tfrom=$cid;
$tr->tto='102';
$tr->plano_contas=$plano;
$tr->centro_custo=$cc;
$tr->amount=$valoritem;
$tr->date = date('Y-m-d');
$tr->memo=$memos;
$tr->status='Completed';
}
parei aqui, mas quando eu verifico na minha tabela "Transactions" só tem um registro referente ao id, teria que ter os dois que mostrou no rowCount() quando dei o vardump...
Se você der um print_r no array vai entender o porque de só estar gravando um registro e 'ignorando' o outro, o jeito mais simples, em vez de usar fetchAll e foreach, use o fetch dentro de um while, assim você rodará resultado por resultado do BD.