MC
Erro ao Gravar registro Mestre-Detalhe com SQL Server
Conectei ao SQL Server 2008 e montei um form Master/Detail para inserir alguns registros.
Me baseei em uma outra tela Master/Detail que eu já tinha construido conectando ao MySQL.
Ao tentar gravar o registro no form, ocorre o seguinte erro:
SQLSTATE[22018]: [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Conversion failed when converting the varchar value '3::Farinha Branca Nico' to data type int.
O mesmo form, alterando a string de conexão e apontando para o MySQL, com exatamente a mesma estrutura de campos e tipos, funciona.
Porém ao apontar a conexão para o SQL Server ocorre o erro acima.
Já li o artigo do Regis falando sobre SQL Server X Adianti. Segui tudo que estava ali e funcionou a conexão e outros aspectos, porém esse detalhe tem me dado dor de cabeça.
Não sei se posso estar fazendo algo errado, alguém pode me ajudar?
Segue abaixo o código do meu form:
Me baseei em uma outra tela Master/Detail que eu já tinha construido conectando ao MySQL.
Ao tentar gravar o registro no form, ocorre o seguinte erro:
SQLSTATE[22018]: [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Conversion failed when converting the varchar value '3::Farinha Branca Nico' to data type int.
O mesmo form, alterando a string de conexão e apontando para o MySQL, com exatamente a mesma estrutura de campos e tipos, funciona.
Porém ao apontar a conexão para o SQL Server ocorre o erro acima.
Já li o artigo do Regis falando sobre SQL Server X Adianti. Segui tudo que estava ali e funcionou a conexão e outros aspectos, porém esse detalhe tem me dado dor de cabeça.
Não sei se posso estar fazendo algo errado, alguém pode me ajudar?
Segue abaixo o código do meu form:
- <?php
- <?php
- /**
- * PesquisaCabForm Master/Detail
- * @author <your name here>
- */
- class PesquisaCabForm extends TPage
- {
- protected $form; // form
- protected $table_details;
- protected $detail_row;
-
- /**
- * Class constructor
- * Creates the page and the registration form
- */
- function __construct($param)
- {
- parent::__construct($param);
-
- // creates the form
- $this->form = new TForm('form_PesquisaCab');
- $this->form->class = 'tform'; // CSS class
-
- $table_master = new TTable;
- $table_master->width = '100%';
-
- $table_master->addRowSet( new TLabel('PesquisaCab'), '', '')->class = 'tformtitle';
-
- // add a table inside form
- $table_general = new TTable;
- $table_general->width = '100%';
-
- $frame_general = new TFrame;
- $frame_general->class = 'tframe tframe-custom';
- $frame_general->setLegend('PesquisaCab');
- $frame_general->style = 'background:whiteSmoke';
- $frame_general->add($table_general);
-
- $frame_details = new TFrame;
- $frame_details->class = 'tframe tframe-custom';
- $frame_details->setLegend('PesquisaItem');
-
- $table_master->addRow()->addCell( $frame_general )->colspan=2;
- $row = $table_master->addRow();
- $row->addCell( $frame_details );
-
- $this->form->add($table_master);
-
- // master fields
- $id = new TEntry('id');
- $promotor_id = new ">TDBSeekButton('promotor_id', 'promotor', 'form_PesquisaCab', 'promotor', 'Nome', 'promotor_id', 'promotorNome');
- $promotorNome = new TEntry('promotorNome');
- $cliente_id = new ">TDBSeekButton('cliente_id', 'promotor', 'form_PesquisaCab', 'cliente', 'Nome', 'cliente_id', 'clienteNome');
- $clienteNome = new TEntry('clienteNome');
- $dataPesq = new TDate('dataPesq');
- $horaPesq = new TEntry('horaPesq');
- $obsPesq = new TText('obsPesq');
- // sizes
- $id->setSize('100');
- $promotor_id->setSize('100');
- $promotorNome->setSize('300');
- $promotorNome->setEditable(FALSE);
- $cliente_id->setSize('100');
- $clienteNome->setSize('300');
- $clienteNome->setEditable(FALSE);
- $dataPesq->setSize('100');
- $dataPesq->setEditable(FALSE);
- $horaPesq->setSize('200');
- $horaPesq->setEditable(FALSE);
- $obsPesq->setSize('200');
- if (!empty($id))
- {
- $id->setEditable(FALSE);
- }
-
- // add form fields to be handled by form
- $this->form->addField($id);
- $this->form->addField($promotor_id);
- $this->form->addField($cliente_id);
- $this->form->addField($dataPesq);
- $this->form->addField($horaPesq);
- $this->form->addField($obsPesq);
-
- // add form fields to the screen
- $table_general->addRowSet( new TLabel('Id'), $id );
- $table_general->addRowSet( $label_promotor = new TLabel('Promotor'), array( $promotor_id, $promotorNome ) );
- $table_general->addRowSet( $label_cliente = new TLabel('Cliente'), array( $cliente_id, $clienteNome ) );
- $table_general->addRowSet( new TLabel('Data'), $dataPesq );
- $table_general->addRowSet( new TLabel('Hora'), $horaPesq );
- $table_general->addRowSet( new TLabel('Observações'), $obsPesq );
-
- // detail
- $this->table_details = new TTable;
- $this->table_details-> width = '100%';
- $frame_details->add($this->table_details);
-
- $this->table_details->addSection('thead');
- $row = $this->table_details->addRow();
-
- // detail header
- $row->addCell( new TLabel('Produto Equivalente') );
- $row->addCell( new TLabel('Descrição') );
- $row->addCell( new TLabel('Marca') );
- $row->addCell( new TLabel('Preço') );
-
- // create an action button (save)
- $save_button=new TButton('save');
- $save_button->setAction(new TAction(array($this, 'onSave')), _t('Save'));
- $save_button->setImage('ico_save.png');
- // create an new button (edit with no parameters)
- $new_button=new TButton('new');
- $new_button->setAction(new TAction(array($this, 'onClear')), _t('New'));
- $new_button->setImage('ico_new.png');
-
- // define form fields
- $this->form->addField($save_button);
- $this->form->addField($new_button);
-
- $table_master->addRowSet( array($save_button, $new_button), '', '')->class = 'tformaction'; // CSS class
-
- $this->detail_row = 0;
-
- // create the page container
- $container = new TVBox;
- $container->style = 'width: 100%';
- //$container->add(new TXMLBreadCrumb('menu.xml', __CLASS__));
- $container->add($this->form);
- parent::add($container);
- }
-
- /**
- * Executed whenever the user clicks at the edit button da datagrid
- */
- function onEdit($param)
- {
- try
- {
- TTransaction::open('promotor');
-
- if (isset($param['key']))
- {
- $key = $param['key'];
-
- $object = new PesquisaCab($key);
- $this->form->setData($object);
-
- $items = PesquisaItem::where('pesquisaCab_id', '=', $key)->load();
-
- $this->table_details->addSection('tbody');
- if ($items)
- {
- foreach($items as $item )
- {
- $this->addDetailRow($item);
- }
-
- // create add button
- $add = new TButton('clone');
- $add->setLabel('Add');
- $add->setImage('fa:plus-circle green');
- $add->addFunction('ttable_clone_previous_row(this)');
-
- // add buttons in table
- $this->table_details->addRowSet([$add]);
- }
- else
- {
- $this->onClear($param);
- }
-
- TTransaction::close(); // close transaction
- }
- }
- catch (Exception $e) // in case of exception
- {
- new TMessage('error', $e->getMessage());
- TTransaction::rollback();
- }
-
- try
- {
- if (isset($param['id']))
- {
- // open a transaction with database 'mvadmin'
- TTransaction::open('promotor');
- // get the parameter $key
- $key = $param['id'];
- // instantiates object Promotor
- $object = new PesquisaCab($key);
-
- $object->promotorNome = $object->promotor->Nome;
- $object->clienteNome = $object->cliente->Nome;
-
- // fill the form with the active record data
- $this->form->setData($object);
- // close the transaction
- TTransaction::close();
- }
- else
- {
- $this->form->clear();
- }
- }
- catch (Exception $e) // in case of exception
- {
- // shows the exception error message
- new TMessage('error', 'Error ' . $e->getMessage());
- // undo all pending operations
- TTransaction::rollback();
- }
- }
-
- /**
- * Add detail row
- */
- public function addDetailRow($item)
- {
- $uniqid = mt_rand(1000000, 9999999);
-
- // create fields
- // $produto_id = new TEntry('produto_id[]');
- $produto_id = new TDBMultiSearch('produto_id[]', 'promotor', 'produto', 'id', 'descricao');
- $descItem = new TEntry('descItem[]');
- $marcaItem = new TEntry('marcaItem[]');
- $valorItem = new TEntry('valorItem[]');
- // set id's
- $produto_id->setId('produto_id_'.$uniqid);
- $descItem->setId('descItem_'.$uniqid);
- $marcaItem->setId('marcaItem_'.$uniqid);
- $valorItem->setId('valorItem_'.$uniqid);
- // set sizes
- $produto_id->setSize('200');
- $descItem->setSize('200');
- $marcaItem->setSize('200');
- $valorItem->setSize('200');
- $produto_id->setMaxSize(1);
- $produto_id->setMinLength(1);
-
- // set row counter
- $produto_id->{'data-row'} = $this->detail_row;
- $descItem->{'data-row'} = $this->detail_row;
- $marcaItem->{'data-row'} = $this->detail_row;
- $valorItem->{'data-row'} = $this->detail_row;
- // set value
- // if (!empty($item->produto_id)) { $produto_id->setValue( $item->produto_id ); }
- if (!empty($item->produto_id)) { $produto_id->setValue( [$item->produto_id => $item->produto->descricao . " ({$item->produto_id})"] ); }
- if (!empty($item->descItem)) { $descItem->setValue( $item->descItem ); }
- if (!empty($item->marcaItem)) { $marcaItem->setValue( $item->marcaItem ); }
- if (!empty($item->valorItem)) { $valorItem->setValue( $item->valorItem ); }
-
- // create delete button
- $del = new TImage('fa:trash-o red');
- $del->onclick = 'ttable_remove_row(this)';
-
- $row = $this->table_details->addRow();
- // add cells
- $row->addCell($produto_id);
- $row->addCell($descItem);
- $row->addCell($marcaItem);
- $row->addCell($valorItem);
-
- $row->addCell( $del );
- $row->{'data-row'} = $this->detail_row;
-
- // add form field
- $this->form->addField($produto_id);
- $this->form->addField($descItem);
- $this->form->addField($marcaItem);
- $this->form->addField($valorItem);
-
- $this->detail_row ++;
- }
-
- /**
- * Clear form
- */
- public function onClear($param)
- {
- $this->table_details->addSection('tbody');
- $this->addDetailRow( new stdClass );
-
- // create add button
- $add = new TButton('clone');
- $add->setLabel('Add');
- $add->setImage('fa:plus-circle green');
- $add->addFunction('ttable_clone_previous_row(this)');
-
- // add buttons in table
- $this->table_details->addRowSet([$add]);
- }
-
- /**
- * Save the PesquisaCab and the PesquisaItem's
- */
- public static function onSave($param)
- {
- try
- {
- TTransaction::open('promotor');
-
- $id = (int) $param['id'];
- $master = new PesquisaCab;
- $master->fromArray( $param);
- $master->store(); // save master object
-
- // delete details
- PesquisaItem::where('pesquisaCab_id', '=', $master->id)->delete();
-
- if( !empty($param['produto_id']) AND is_array($param['produto_id']) )
- {
- foreach( $param['produto_id'] as $row => $produto_id)
- {
- if (!empty($produto_id))
- {
- $detail = new PesquisaItem;
- $detail->pesquisaCab_id = $master->id;
- $detail->produto_id = $param['produto_id'][$row];
- $detail->descItem = $param['descItem'][$row];
- $detail->marcaItem = $param['marcaItem'][$row];
- $detail->valorItem = $param['valorItem'][$row];
- $detail->store();
- }
- }
- }
-
- $data = new stdClass;
- $data->id = $master->id;
- TForm::sendData('form_PesquisaCab', $data);
- TTransaction::close(); // close the transaction
-
- new TMessage('info', TAdiantiCoreTranslator::translate('Record saved'));
- }
- catch (Exception $e) // in case of exception
- {
- new TMessage('error', $e->getMessage());
- TTransaction::rollback();
- }
- }
- }
- ?>
Marcelo, o erro diz que você está tentando salvar um varchar em um campo int. O Mysql deve converter automaticamente e por isso não apresenta o erro. Como a função onSave é static alguns tratamentos dos campos não são feitos automaticamente. Você precisa extrair somente o id do produto antes de salvar cada detalhe:
Obrigado Nataniel. Funcionou perfeitamente.
Olá, estava com este mesmo problema.aApós criar o formulário mestre/detalhe com o Studio, resolvi utilizando as informações que o Nataniel informou.
Entretanto só consigo adicionar até o terceiro registro, aparece a mensagem que o "registro foi salvo ".
Mas no banco de dados da tabela referente ao registro de detalhe, todos os campos ficam gravados com NULL.
Obs.: Um detalhe interessante, se eu for na base de dados e incluir manualmente algum registro, por ex: "nome", ao voltar para a datagrid referente e selecionar o registro com os campos null, consigo salvar no banco de dados os outros registros através do formulário.
Também estou no sql server e estou tendo dificuldade em gravar o id do mestre no detalhe. O id do mestre, que normalmente fica disponível após o $master->store(); simplesmente não grava no detalhe, apesar de gravar o mestre corretamente no banco de dados. Mesmo na página gerada pelo studio está dando este problema.