11
respostas

JOIN SQL SERVER com PDO PHP

Olá pessoal,

Estou com um problema em uma query com JOIN. Não sei porque, mas de algum modo o PDO não está associando as tabelas, mesmo com os IDs corretos.

$sql = "SELECT  p.id AS parcela_id, c.id AS conta_id, 
         p.data_vencimento, p.data_prorrogacao, p.data_pagamento,
         c.empresa_devedora_id, e.nome, 
         p.valor_pagar, p.status, c.dre_id,
         p.numero_parcela, total_parcela,
         e.nome AS nomeEmpresaDevedora, 
         '2019-04-17' AS data_inicial, 
         '2019-04-17' AS data_final
   FROM parcelas_pagar p
   LEFT JOIN contas_pagar    AS c ON c.id = p.id
   LEFT JOIN empresas        AS e ON e.id = c.empresa_devedora_id
WHERE  p.data_vencimento BETWEEN '2019-04-17' AND '2019-04-17'
ORDER BY nomeEmpresaDevedora, p.valor_pagar";

$sql = $this->db->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));

$array = $sql->fetchAll();

Alguém sabe o que poderia ser?

Eu criei uma imagem do resultado das queries mas não sei como coloco a imagem aqui.

11 respostas

O erro está em associar id da conta com id da parcela, imagino que a tabela parcela contenha o id da conta em um campo específico! "FROM parcelas_pagar p LEFT JOIN contas_pagar c ON p.conta_id = c.id;". Desaconselho o uso de "AS", para nomear campos, tabelas... ele não é aceito por todos os bancos de dados. Mesmo que esteja estudando um em específico, é sempre bom já manter o aprendizado mais adaptável.

Olá Euler,

Sim a query original fiz no MySQL e funciona!

Fui migrar para o SQL Server e ele não associa, vem null nos IDs.

Então você está dizendo que não posso renomear as campos? porque nas minhas tabelas uso apenas o id...

Faz falta então no PHP ter um framework que encapsula e trata as conexões e transações com Banco de Dados.

Não, Ivan. O que o Euler disse é que sua query está errada nessa parte: LEFT JOIN contas_pagar AS c ON c.id = p.id

Você está comparando o id de uma tabela com o id de outra.

Execute sua query diretamente no SQL Server e verá que o resultado não é o esperado.

Quando a um "framework" no PHP que te ajude com o banco de dados, já existe o Doctrine (dentre outros), mas aconselho você a dominar o PDO antes de prosseguir para estudar outras ferramentas.

:-D

Forte abraço e bons estudos.

Agora, só de curiosidade, Ivan.

Por que você está utilizando o PDO::CURSOR_SCROLL?

Olá Vinicius, estava testando algumas opções para ver o resultado...

Referente ao LEFT JOIN, originalmente a query que fiz no MySQL era INNER JOIN e funcionava. Quando fui rodar no SQL Server, não vinha nenhum resultado. Alterei para LEFT Join para testar. Aí percebi que as referências não vinham. Mas pelo o que vocês falaram, não basta mudar a cláusula de INNER para LEFT...

Ah! E obrigado pelo conselho!

Pois é, Ivan. Os resultados que estavam vindo no MySQL com certeza estavam com os relacionamentos errados. =/

Vinicius,

Mas para você ter uma ideia, para fazer um INSERT com o MySQL bastava o comando:

$sql = $this->db->prepare($sql);

Para fazer a mesma ação no SQL Server, me ensinaram a colocar no prepare:

 $sql = $this->db->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));

sem esse array(PDO...) com SQL Server não dava erro mas o insert não funcionava...

Ivan, trabalhei um tempinho com SQL Server e nunca precisei adicionar esse parâmetro.

O PDO::CURSOR_SCROLL serve para você conseguir manipular o retorno de uma forma diferente do padrão...

Sem esse parâmetro não funciona? Tem certeza? Como está esse INSERT?

Olá Vinicius, segue um exemplo de um formulário de um model de uma classe simples:

public function add($nome, $email, $status) {
            if($this->nomeExists($nome) == false) {
                $sql = "INSERT INTO areas (nome, email, status) 
                            VALUES (:nome, :email, :status)";

                $sql = $this->db->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));

                $sql->bindValue(":nome", $nome);
                $sql->bindValue(":email", $email);
                $sql->bindValue(":status", $status);

                try {
                    $this->db->beginTransaction();
                    $sql->execute();
                    $this->db->commit(); 
                    return true;
                } catch(PDOException $e) {               

                    echo $e;                

                    $this->db->rollback();

                    /* die(); */
                    return false;
                }            

            } else {
                return false;
            }

        }

A diferença, era que antes não tinha esse array no prepare...

aqui também o config de conexão:

Ja não sei como estava antes...

if(ENVIRONMENT == 'development') {
    define("BASE_URL", "http://localhost/PortPar/");
    $config['dbname'] = 'sdp;charset=utf8';
    $config['host'] = 'localhost';
    $config['dbuser'] = 'root';
    $config['dbpass'] = 'estudo';
} else {
    define("BASE_URL", "http://IPCOMERCIAL/PortPar/");
    $config['dbname'] = 'sdp;charset=utf8';
    $config['host'] = 'localhost';
    $config['dbuser'] = 'root';
    $config['dbpass'] = '';
}

global $db;
try {
    $db = new PDO("mysql:dbname=".$config['dbname'].";host=".$config['host'], $config['dbuser'], $config['dbpass']);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
} catch(PDOException $e) {
    echo "ERRO: ".$e->getMessage();
    exit;
}

quando tentei trabalhar com o SQL Server, me indicaram assim:

global $db;
try {
    $db = new PDO($pdoConfig2, $pdoUser2, $pdoPass2);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);   
    $db->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
    $db->setAttribute(constant('PDO::SQLSRV_ATTR_DIRECT_QUERY'), false);
    $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);  
} catch(PDOException $e) {
    echo "ERRO: ".$e->getMessage();
    exit;
}

Fiz um teste agora e mudei a conexão para MySQL e a query funcionou... :\

Ivan, por partes:

  1. Executa sua Query no num cliente SQL Server, fora do PHP e diz o que acontece
  2. Que erro você tá recebendo ao tentar executar a query com o PDO?
  3. Por que você tá usando PDO::CURSOR_SCROLL? Acontece algo de diferente quando não o usa?