Autor Tópico: Pegar o ultimo ID Gravado <Resolvido>  (Lida 636 vezes)

Marculino

  • Iniciante
  • **
  • Mensagens: 59
    • Email
Pegar o ultimo ID Gravado <Resolvido>
« Online: Dezembro 04, 2015, 03:11:54 pm »
Pessoal estou usando banco de dados postgresSQL e nele tenho uma tabela chamada empresa que possue um campo idempres que é auto incremete ou (Serial no postgre) e o banco de dados tem concorrencia, mais de uma pessoa pode dazer a mesma transação.

Eu preciso fazer um insert na tabela empresa e pegar o idempresa que foi gerado e mandar para outra tabela.

Eu fiz uma aplicação do tipo controle e nela no evento onValidateSuccess fiz assim:

/**
 * Insert a record on another table
 */

// SQL statement parameters
$insert_table_empresa  = 'empresa';      // Table name
$insert_fields_empresa = array(   // Field list, add as many as needed
   'razao_social' => "'{razao_social}'",
   'nome_fantasia' => "'{nome_fantasia}'",
   'cnpj' => "'{cnpj}'",
   'cep' => "'{cep}'",
   'logradouro' => "'{logradouro}'",
   'numero' => "'{numero}'",
   'bairro' => "'{bairro}'",
   'cidade' => "'{cidade}'",
   'complemento' => "'{complemento}'",
   'uf' => "'{uf}'",
   'ramo_de_atividade' => "'{ramo_de_atividade}'",
   'tel1' => "'{tel1}'",
   'tel2' => "'{tel2}'",
   'email' => "'{email_da_empresa}'",
   'data_do_cadastro' => "'{data_do_cadastro}'",
 );

// Insert record 1ª forma de pegar o idempresa é usar o comando RETURNING  Currval('serial_seq_empresa_idempresa')
$insert_sql_empresa = "INSERT INTO " . $insert_table_empresa
    . " ("   . implode(", ", array_keys($insert_fields_empresa))   . ")"
    . " VALUES ("    . implode(", ", array_values($insert_fields_empresa)) . ") RETURNING  Currval('serial_seq_empresa_idempresa')";

sc_exec_sql($insert_sql_empresa);

Segunda forma que usei foi:
$insert_sql_empresa = "INSERT INTO " . $insert_table_empresa
    . " ("   . implode(", ", array_keys($insert_fields_empresa))   . ")"
    . " VALUES ("    . implode(", ", array_values($insert_fields_empresa)) . ") RETURNING idempresa";

sc_exec_sql($insert_sql_empresa);

como pegar este retorno?

Se eu executar o comando direto no banco funciona:
Exemplo direto no banco:
INSERT INTO empresa (razao_social, nome_fantasia, cnpj, cep, logradouro, numero, bairro, cidade, complemento, uf, ramo_de_atividade, tel1, tel2, email, data_do_cadastro) VALUES ('zvadvf', '', '18659920000181', '37980000', 'w35wetrwer', '2341', '', 'Cássia', '', 'MG', '', '35354112880', '', 'ffwfewfwef@hotmail.com', '20151204') RETURNING Currval('serial_seq_empresa_idempresa')

ou
INSERT INTO empresa (razao_social, nome_fantasia, cnpj, cep, logradouro, numero, bairro, cidade, complemento, uf, ramo_de_atividade, tel1, tel2, email, data_do_cadastro) VALUES ('zvadvf', '', '18659920000181', '37980000', 'w35wetrwer', '2341', '', 'Cássia', '', 'MG', '', '35354112880', '', 'werwerwer@hotmail.com', '20151204') RETURNING idempresa
« Última modificação: Dezembro 11, 2015, 12:35:21 pm por Marculino »

Haroldo

  • Expert
  • *****
  • Mensagens: 6293
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Pegar o ultimo ID Gravado
« Responder #1 Online: Dezembro 04, 2015, 07:40:02 pm »
sc_lookup(ds,"SELECT LAST_RECORD_ID");


Alexandre Pereira Bühler

  • Expert
  • *****
  • Mensagens: 1658
  • Nunca estabeleça um teto para os seus rendimentos.
    • Simão & Bühler Ltda
    • Email
Re:Pegar o ultimo ID Gravado
« Responder #2 Online: Dezembro 05, 2015, 02:25:32 pm »
Haroldo,
Está não é uma função somente do mysql?
Postgresql tem last_insert_id()?
--
Alexandre Pereira Bühler
https://www.simaoebuhler.com.br
Hospedagem compartilhada Scriptcase desenvolvimento e produção. Temos servidores dedicados Scriptcase.
Eu RTFM todo dia e você?

Alexandre Pereira Bühler

  • Expert
  • *****
  • Mensagens: 1658
  • Nunca estabeleça um teto para os seus rendimentos.
    • Simão & Bühler Ltda
    • Email
Re:Pegar o ultimo ID Gravado
« Responder #3 Online: Dezembro 05, 2015, 02:31:25 pm »
Recorri ao manual do postgresql:
http://www.postgresql.org/docs/9.4/static/functions-sequence.html
Neste caso acho que terá que usar "currval".
Exemplo:
SELECT CURRVAL( pg_get_serial_sequence('nome_da_sua_tabela','id_nome_da_coluna')); -> para uma sequência específica
SELECT lastval(); -> para qualquer sequência
« Última modificação: Dezembro 05, 2015, 02:34:37 pm por Alexandre Pereira Bühler »
--
Alexandre Pereira Bühler
https://www.simaoebuhler.com.br
Hospedagem compartilhada Scriptcase desenvolvimento e produção. Temos servidores dedicados Scriptcase.
Eu RTFM todo dia e você?

Marculino

  • Iniciante
  • **
  • Mensagens: 59
    • Email
Re:Pegar o ultimo ID Gravado
« Responder #4 Online: Dezembro 09, 2015, 08:43:23 am »
A questão de concorrência:
Imagina comigo: eu tenho a tabela empresa com o idempresa que é auto increment(serial no postgres) eu tenho que fazer o insert nela pegar o idempresa gerado e mandar para tabela sec_empresa que tem uma fk_idempresa.
 o padrão seria ( insert into empresa (nome) values (empresax)), ai ele iria criar o idempresa = 1 nome=empresax, teria que pegar este idempresa=1 e fazer um ( insert into sec_empresa (fk_idempresa) values (1)), isso funcionaria.

Agora vamos a ideia do nextval e currval:

//aqui como so uma pessoa esta adicionando e não tem concorrência funciona
$oserial = SELECT nextval('serial_seq_empresa_idempresa' ); (imagina que a variavel $oserial vai ser 1)
( insert into empresa (nome) values (empresax))  //vai colocar o serial 1
( insert into sec_empresa (fk_idempresa) values ($oserial)) //vai colocar o serial 1
muito bom é isso mesmo que eu preciso.

Agora vamos pensar com concorrência
João e Maria apertão o botão ao mesmo tempo para cadastrar sua empresa:
$oserial = SELECT nextval('serial_seq_empresa_idempresa' ); (para o joão a variavel $oserial vai ser 1, como maria veio depois vai ser 2)
na hora que eu fizer o insert ( insert into empresa (nome) values (empresax))  do joão que veio na frente na tabela empresa recebera o id 2 porque toda vez que eu executo o comando $oserial = SELECT nextval('serial_seq_empresa_idempresa' );  ele altera o valor da sequencia automaticamente.
ai vai ficar assim:
joão
( insert into empresa (nome) values (empresax))  //vai colocar o serial 2
( insert into sec_empresa (fk_idempresa) values ($oserial)) //vai colocar o serial 1

Maria
( insert into empresa (nome) values (empresax))  //vai colocar o serial 3
( insert into sec_empresa (fk_idempresa) values ($oserial)) //vai colocar o serial 2

se meu pensamento estiver errado me corrijam por favor.

Jailton

  • Expert
  • *****
  • Mensagens: 2041
Re:Pegar o ultimo ID Gravado
« Responder #5 Online: Dezembro 09, 2015, 09:07:09 am »
A questão de concorrência:
Imagina comigo: eu tenho a tabela empresa com o idempresa que é auto increment(serial no postgres) eu tenho que fazer o insert nela pegar o idempresa gerado e mandar para tabela sec_empresa que tem uma fk_idempresa.
 o padrão seria ( insert into empresa (nome) values (empresax)), ai ele iria criar o idempresa = 1 nome=empresax, teria que pegar este idempresa=1 e fazer um ( insert into sec_empresa (fk_idempresa) values (1)), isso funcionaria.

Agora vamos a ideia do nextval e currval:

//aqui como so uma pessoa esta adicionando e não tem concorrência funciona
$oserial = SELECT nextval('serial_seq_empresa_idempresa' ); (imagina que a variavel $oserial vai ser 1)
( insert into empresa (nome) values (empresax))  //vai colocar o serial 1
( insert into sec_empresa (fk_idempresa) values ($oserial)) //vai colocar o serial 1
muito bom é isso mesmo que eu preciso.

Agora vamos pensar com concorrência
João e Maria apertão o botão ao mesmo tempo para cadastrar sua empresa:
$oserial = SELECT nextval('serial_seq_empresa_idempresa' ); (para o joão a variavel $oserial vai ser 1, como maria veio depois vai ser 2)
na hora que eu fizer o insert ( insert into empresa (nome) values (empresax))  do joão que veio na frente na tabela empresa recebera o id 2 porque toda vez que eu executo o comando $oserial = SELECT nextval('serial_seq_empresa_idempresa' );  ele altera o valor da sequencia automaticamente.
ai vai ficar assim:
joão
( insert into empresa (nome) values (empresax))  //vai colocar o serial 2
( insert into sec_empresa (fk_idempresa) values ($oserial)) //vai colocar o serial 1

Maria
( insert into empresa (nome) values (empresax))  //vai colocar o serial 3
( insert into sec_empresa (fk_idempresa) values ($oserial)) //vai colocar o serial 2

se meu pensamento estiver errado me corrijam por favor.


Para evitar isso, na hora de dar o insert grava também a sessão Id do PHP ela é única por usuário acessando o seu sistema,
ai você recupera o registro gerado usando a seção no where:
$a = session_id();
O Princípio da Vibração. "Nada está parado, tudo se move, tudo vibra". Caibalion.

Marculino

  • Iniciante
  • **
  • Mensagens: 59
    • Email
Re:Pegar o ultimo ID Gravado
« Responder #6 Online: Dezembro 10, 2015, 01:06:20 pm »
A questão de concorrência:
Imagina comigo: eu tenho a tabela empresa com o idempresa que é auto increment(serial no postgres) eu tenho que fazer o insert nela pegar o idempresa gerado e mandar para tabela sec_empresa que tem uma fk_idempresa.
 o padrão seria ( insert into empresa (nome) values (empresax)), ai ele iria criar o idempresa = 1 nome=empresax, teria que pegar este idempresa=1 e fazer um ( insert into sec_empresa (fk_idempresa) values (1)), isso funcionaria.

Agora vamos a ideia do nextval e currval:

//aqui como so uma pessoa esta adicionando e não tem concorrência funciona
$oserial = SELECT nextval('serial_seq_empresa_idempresa' ); (imagina que a variavel $oserial vai ser 1)
( insert into empresa (nome) values (empresax))  //vai colocar o serial 1
( insert into sec_empresa (fk_idempresa) values ($oserial)) //vai colocar o serial 1
muito bom é isso mesmo que eu preciso.

Agora vamos pensar com concorrência
João e Maria apertão o botão ao mesmo tempo para cadastrar sua empresa:
$oserial = SELECT nextval('serial_seq_empresa_idempresa' ); (para o joão a variavel $oserial vai ser 1, como maria veio depois vai ser 2)
na hora que eu fizer o insert ( insert into empresa (nome) values (empresax))  do joão que veio na frente na tabela empresa recebera o id 2 porque toda vez que eu executo o comando $oserial = SELECT nextval('serial_seq_empresa_idempresa' );  ele altera o valor da sequencia automaticamente.
ai vai ficar assim:
joão
( insert into empresa (nome) values (empresax))  //vai colocar o serial 2
( insert into sec_empresa (fk_idempresa) values ($oserial)) //vai colocar o serial 1

Maria
( insert into empresa (nome) values (empresax))  //vai colocar o serial 3
( insert into sec_empresa (fk_idempresa) values ($oserial)) //vai colocar o serial 2

se meu pensamento estiver errado me corrijam por favor.


Para evitar isso, na hora de dar o insert grava também a sessão Id do PHP ela é única por usuário acessando o seu sistema,
ai você recupera o registro gerado usando a seção no where:
$a = session_id();


Poderia me passar o seu pensamento, fiquei sem entender como fazer esta lógica.
Seria assim?

$oserial = SELECT nextval('serial_seq_empresa_idempresa' );
$a = session_id();//depois que eu pegar o id da sessão não sei o que fazer, vc falou para colocar no where.

insert into empresa (nome) values (empresax)
insert into sec_empresa (fk_idempresa) values ($oserial)

Jailton

  • Expert
  • *****
  • Mensagens: 2041
Re:Pegar o ultimo ID Gravado
« Responder #7 Online: Dezembro 10, 2015, 01:12:42 pm »
Esse $a = session_id você vai gravar ele no banco em um novo campo, ai quando você pegar o maior número gerado, você puxa ele junto com o ID no banco, que ele vai te trazer
o ID máximo correto somente daquele usuário no momento que ele deu o INSERT, isso para evitar que 2 usuários gravem o registro ao mesmo tempo e peguem o mesmo ID.
O Princípio da Vibração. "Nada está parado, tudo se move, tudo vibra". Caibalion.

Marculino

  • Iniciante
  • **
  • Mensagens: 59
    • Email
Re:Pegar o ultimo ID Gravado
« Responder #8 Online: Dezembro 11, 2015, 10:31:46 am »
Esse $a = session_id você vai gravar ele no banco em um novo campo, ai quando você pegar o maior número gerado, você puxa ele junto com o ID no banco, que ele vai te trazer
o ID máximo correto somente daquele usuário no momento que ele deu o INSERT, isso para evitar que 2 usuários gravem o registro ao mesmo tempo e peguem o mesmo ID.

Segundo sua ideia eu fiz o seguinte:
//eu pego o id da sesão e gravo no banco de dados para eliminar concorrencia
$id_da_sessao=session_id();
/**
 * Insert a record on another table
 */

// SQL statement parameters
$insert_table_empresa  = 'empresa';      // Table name
$insert_fields_empresa = array(   // Field list, add as many as needed
   'razao_social' => "'{razao_social}'",
   'nome_fantasia' => "'{nome_fantasia}'",
   'cnpj' => "'{cnpj}'",
   'cep' => "'{cep}'",
   'logradouro' => "'{logradouro}'",
   'numero' => "'{numero}'",
   'bairro' => "'{bairro}'",
   'cidade' => "'{cidade}'",
   'complemento' => "'{complemento}'",
   'uf' => "'{uf}'",
   'ramo_de_atividade' => "'{ramo_de_atividade}'",
   'tel1' => "'{tel1}'",
   'tel2' => "'{tel2}'",
   'email' => "'{email_da_empresa}'",
   'data_do_cadastro' => "'{data_do_cadastro}'",
   'sessao_id_temp' => "'{$id_da_sessao}'",
 );


   
$insert_sql_empresa = 'INSERT INTO ' . $insert_table_empresa
   . ' ('   . implode(', ', array_keys($insert_fields_empresa))   . ')'
   . ' VALUES ('    . implode(', ', array_values($insert_fields_empresa)).')';

sc_exec_sql($insert_sql_empresa);
   



/** Selecting a field from another table*/

// Check for record
$check_sql_empresa = "SELECT idempresa"
   . " FROM empresa"
   . " WHERE sessao_id_temp = '" . $id_da_sessao . "'";
sc_lookup(rs_empresa, $check_sql_empresa);

if (isset({rs_empresa[0][0]})) {   

    $id_empresa = {rs_empresa[0][0]};
   $insert_table_sec_user  = 'sec_users';
   $insert_fields_sec_user = array(   // Field list, add as many as needed
      'login' => "'{login}'",
      'active' => "'{Active}'",
      'priv_admin' => "'{Priv_Admin}'",
      'pswd' => "'{pswd}'",
      'name' => "'{name}'",
      'email' => "'{email}'",
      'empresa_idempresa' => "' $id_empresa'",
   );
   
   $insert_sql_sc_user = 'INSERT INTO ' . $insert_table_sec_user
      . ' ('   . implode(', ', array_keys($insert_fields_sec_user))   . ')'
      . ' VALUES ('    . implode(', ', array_values($insert_fields_sec_user)) . ')';

   sc_exec_sql($insert_sql_sc_user);


}else{   
   // No row found
       //para eu estudar - agora deveria eu colocar aqui um delet caso falhe a inserção no banco sec_users?
}


sc_commit_trans();
sc_redir('app_sec_Login');

Olha se era esta sua ideia.

Jailton

  • Expert
  • *****
  • Mensagens: 2041
Re:Pegar o ultimo ID Gravado
« Responder #9 Online: Dezembro 11, 2015, 11:28:06 am »
Esse $a = session_id você vai gravar ele no banco em um novo campo, ai quando você pegar o maior número gerado, você puxa ele junto com o ID no banco, que ele vai te trazer
o ID máximo correto somente daquele usuário no momento que ele deu o INSERT, isso para evitar que 2 usuários gravem o registro ao mesmo tempo e peguem o mesmo ID.

Segundo sua ideia eu fiz o seguinte:
//eu pego o id da sesão e gravo no banco de dados para eliminar concorrencia
$id_da_sessao=session_id();
/**
 * Insert a record on another table
 */

// SQL statement parameters
$insert_table_empresa  = 'empresa';      // Table name
$insert_fields_empresa = array(   // Field list, add as many as needed
   'razao_social' => "'{razao_social}'",
   'nome_fantasia' => "'{nome_fantasia}'",
   'cnpj' => "'{cnpj}'",
   'cep' => "'{cep}'",
   'logradouro' => "'{logradouro}'",
   'numero' => "'{numero}'",
   'bairro' => "'{bairro}'",
   'cidade' => "'{cidade}'",
   'complemento' => "'{complemento}'",
   'uf' => "'{uf}'",
   'ramo_de_atividade' => "'{ramo_de_atividade}'",
   'tel1' => "'{tel1}'",
   'tel2' => "'{tel2}'",
   'email' => "'{email_da_empresa}'",
   'data_do_cadastro' => "'{data_do_cadastro}'",
   'sessao_id_temp' => "'{$id_da_sessao}'",
 );


   
$insert_sql_empresa = 'INSERT INTO ' . $insert_table_empresa
   . ' ('   . implode(', ', array_keys($insert_fields_empresa))   . ')'
   . ' VALUES ('    . implode(', ', array_values($insert_fields_empresa)).')';

sc_exec_sql($insert_sql_empresa);
   



/** Selecting a field from another table*/

// Check for record
$check_sql_empresa = "SELECT idempresa"
   . " FROM empresa"
   . " WHERE sessao_id_temp = '" . $id_da_sessao . "'";
sc_lookup(rs_empresa, $check_sql_empresa);

if (isset({rs_empresa[0][0]})) {   

    $id_empresa = {rs_empresa[0][0]};
   $insert_table_sec_user  = 'sec_users';
   $insert_fields_sec_user = array(   // Field list, add as many as needed
      'login' => "'{login}'",
      'active' => "'{Active}'",
      'priv_admin' => "'{Priv_Admin}'",
      'pswd' => "'{pswd}'",
      'name' => "'{name}'",
      'email' => "'{email}'",
      'empresa_idempresa' => "' $id_empresa'",
   );
   
   $insert_sql_sc_user = 'INSERT INTO ' . $insert_table_sec_user
      . ' ('   . implode(', ', array_keys($insert_fields_sec_user))   . ')'
      . ' VALUES ('    . implode(', ', array_values($insert_fields_sec_user)) . ')';

   sc_exec_sql($insert_sql_sc_user);


}else{   
   // No row found
       //para eu estudar - agora deveria eu colocar aqui um delet caso falhe a inserção no banco sec_users?
}


sc_commit_trans();
sc_redir('app_sec_Login');

Olha se era esta sua ideia.


Sim é isso mesmo.
O Princípio da Vibração. "Nada está parado, tudo se move, tudo vibra". Caibalion.