Update more than one table firebird unidac

Discussion of open issues, suggestions and bugs regarding UniDAC (Universal Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
gss200610
Posts: 35
Joined: Mon 23 May 2016 22:29

Update more than one table firebird unidac

Post by gss200610 » Tue 27 Feb 2018 12:45

how to update data in more than one table using a uniquery with firebird?
I've already changed the read-only fields to false, and I'm using cached update

my sql text :

Code: Select all

select 
    v.cod_ven,
    v.data_ven,
    v.desconto_ven,
    v.cod_tpv,
    v.total_ven,
    v.cupom_fiscal_ven,
    v.total_custo_ven,
    v.data_hora_ven,
    v.desc_pessoa_autorizada,
    v.cod_usu,
    v.cancelada_ven,
    v.codigo_paf,
    v.r04_ccf,
    v.r04_nome_cliente,
    v.r04_cnpj_cliente,
    v.numero_nota_fiscal,
    v.cod_vend,
    v.serie_nota_fiscal,
    v.cer,
    v.consignada,
    v.status_exporta,
    v.r04_nroserie,
    v.endereco_cli,
    v.bairro_cli,
    v.cidade_cli,
    v.uf_cli,
    v.fone_cli,
    v.cep_cli,
    v.num_endereco_cli,
    v.cod_ibge_cli,
    v.cod_abre_fecha,
    c.nome_cli,
    c.endres_cli,
    c.baires_cli,
    c.cidres_cli,
    c.estres_cli,
    c.cepres_cli,
    c.telres_cli,
    c.cnpj_cli,
    c.doc_cli,
    c.insc_estadual,
    c.codigo_ibge,
    c.email_cli,
    c.insc_municipal,
    c.indie_dest,
    c.fj_cli,
    n.cod_nf,
    n.numero_nota_nf,
    n.data_emissao_nf,
    n.data_saida_nf,
    n.hora_saida_nf,
    n.cod_tra,
    n.base_calculo_icms_nf,
    n.valor_icms_nf,
    n.base_subst_nf,
    n.valor_subst_nf,
    n.valor_total_prod_nf,
    n.valor_frete_nf,
    n.valor_seguro_nf,
    n.outras_despesas_nf,
    n.valor_ipi_nf,
    n.valor_total_nf,
    n.especie_nf,
    n.marca_nf,
    n.numero_nf,
    n.inf_compl_nf,
    n.cancelada_nf,
    n.frete_conta_nf,
    n.cod_cli,
    n.cod_for,
    n.desconto_nf,
    n.tipo_cliente,
    n.nota_impressa,
    n.serie_nota,
    n.tipo_nota_fiscal,
    n.codificacao_fiscal,
    n.codigo_outra_entrada,
    n.codigo_outra_saida,
    n.chave_acesso_nfe,
    n.protocolo_nfe,
    n.status_transmitida,
    n.status_retorno,
    n.status_cancelado,
    n.status_inutilizado,
    n.status_email,
    n.justificativa_cancel_inutil,
    n.placa_transp,
    n.uf_placa_transp,
    n.peso_bruto_nf,
    n.peso_liquido_nf,
    n.quantidade_nf,
    n.chave2,
    n.depec,
    n.status_cce,
    n.dhrecbto,
    n.protocolo_cancto,
    n.dhrecbto_canc,
    n.tipoemissao,
    n.idlote_can,
    n.idlote_cce,
    n.xml_nf,
    n.xml_cancelado,
    n.xml_cce,
    n.xml_autorizado,
    n.status_exporta,
    n.idlote_env,
    n.recibo_nfe,
    n.cupons_nfe,
    n.indie_dest,
    n.nfe_ref,
    n.entrada_nf,
    n.desconto_per_nf,
    n.quant_parcelas,
    n.valor_total_parcelas,
    n.diferenca_parcelas,
    n.indpag_nf,
    n.iddest_nf,
    n.finalidade_nf,
    n.indfinal_nf,
    n.indpresenca_nf,
    n.codigo_cnf,
    n.xml_inutilizado,
    n.protocolo_inutilizacao,
    n.dhrecebto_inutilizacao,
    n.nat_operacao,
    n.status_autorizada,
    n.status_denegada,
    n.tipo_es_nf,
    n.icmsdeson_nf,
    n.fcpufdest_nf,
    n.icmsufdest_nf,
    n.icmsufremet_nf,
    n.valor_ii_nf,
    n.valor_pis_nf,
    n.valor_cofins_nf,
    n.valor_trib_nf,
    n.bc_iss_nf,
    n.valor_iss_nf,
    n.valor_pis_iss_nf,
    n.valor_cofins_iss_nf,
    n.dtcomp_iss_nf,
    n.valor_ded_iss_nf,
    n.valor_outro_iss_nf,
    n.descincond_iss_nf,
    n.desccond_iss_nf,
    n.regtrib_iss_nf,
    n.valor_retpis_nf,
    n.valor_retcofins,
    n.valor_retcsll,
    n.base_irrf_nf,
    n.valor_irrf,
    n.base_retprev,
    n.valor_retprev,
    n.inf_ad_fisco,
    n.qr_code,
    n.chave_original
from nota_fiscal n
   left join vendas v on (n.cod_venda = v.cod_ven)
   left join cliente c on (v.cod_cli = c.cod_cli)
where 
   (
      (n.cod_nf = :codnf)
   )
and n.codificacao_fiscal = '65'

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: Update more than one table firebird unidac

Post by ViktorV » Tue 27 Feb 2018 13:11

UniDAC uses the first table specified after "SELECT" or the first table pointed after "FROM" as default updating table, depending from the current data provider.
If your query contains several tables, it is recommended to always set the UpdatingTable property to the table you want to edit.
To edit all data in your query perform the following steps:
- set the TUniQuery.Options.SetFieldsReadOnly property to False
- in TUniQuery.SQLUpdate you should create a correct execute block including queries for updating all the tables taking part in the select query.

gss200610
Posts: 35
Joined: Mon 23 May 2016 22:29

Re: Update more than one table firebird unidac

Post by gss200610 » Tue 27 Feb 2018 13:18

my update sql in uniquery:

Code: Select all

UPDATE NOTA_FISCAL
SET
  COD_NF = :COD_NF, NUMERO_NOTA_NF = :NUMERO_NOTA_NF, DATA_EMISSAO_NF = :DATA_EMISSAO_NF, DATA_SAIDA_NF = :DATA_SAIDA_NF, HORA_SAIDA_NF = :HORA_SAIDA_NF, COD_TRA = :COD_TRA, BASE_CALCULO_ICMS_NF = :BASE_CALCULO_ICMS_NF, VALOR_ICMS_NF = :VALOR_ICMS_NF, BASE_SUBST_NF = :BASE_SUBST_NF, VALOR_SUBST_NF = :VALOR_SUBST_NF, VALOR_TOTAL_PROD_NF = :VALOR_TOTAL_PROD_NF, VALOR_FRETE_NF = :VALOR_FRETE_NF, VALOR_SEGURO_NF = :VALOR_SEGURO_NF, OUTRAS_DESPESAS_NF = :OUTRAS_DESPESAS_NF, VALOR_IPI_NF = :VALOR_IPI_NF, VALOR_TOTAL_NF = :VALOR_TOTAL_NF, ESPECIE_NF = :ESPECIE_NF, MARCA_NF = :MARCA_NF, NUMERO_NF = :NUMERO_NF, INF_COMPL_NF = :INF_COMPL_NF, CANCELADA_NF = :CANCELADA_NF, FRETE_CONTA_NF = :FRETE_CONTA_NF, COD_CLI = :COD_CLI, COD_FOR = :COD_FOR, DESCONTO_NF = :DESCONTO_NF, TIPO_CLIENTE = :TIPO_CLIENTE, NOTA_IMPRESSA = :NOTA_IMPRESSA, SERIE_NOTA = :SERIE_NOTA, TIPO_NOTA_FISCAL = :TIPO_NOTA_FISCAL, CODIFICACAO_FISCAL = :CODIFICACAO_FISCAL, CODIGO_OUTRA_ENTRADA = :CODIGO_OUTRA_ENTRADA, CODIGO_OUTRA_SAIDA = :CODIGO_OUTRA_SAIDA, CHAVE_ACESSO_NFE = :CHAVE_ACESSO_NFE, PROTOCOLO_NFE = :PROTOCOLO_NFE, STATUS_TRANSMITIDA = :STATUS_TRANSMITIDA, STATUS_RETORNO = :STATUS_RETORNO, STATUS_CANCELADO = :STATUS_CANCELADO, STATUS_INUTILIZADO = :STATUS_INUTILIZADO, STATUS_EMAIL = :STATUS_EMAIL, JUSTIFICATIVA_CANCEL_INUTIL = :JUSTIFICATIVA_CANCEL_INUTIL, PLACA_TRANSP = :PLACA_TRANSP, UF_PLACA_TRANSP = :UF_PLACA_TRANSP, PESO_BRUTO_NF = :PESO_BRUTO_NF, PESO_LIQUIDO_NF = :PESO_LIQUIDO_NF, QUANTIDADE_NF = :QUANTIDADE_NF, CHAVE2 = :CHAVE2, DEPEC = :DEPEC, STATUS_CCE = :STATUS_CCE, DHRECBTO = :DHRECBTO, PROTOCOLO_CANCTO = :PROTOCOLO_CANCTO, DHRECBTO_CANC = :DHRECBTO_CANC, TIPOEMISSAO = :TIPOEMISSAO, IDLOTE_CAN = :IDLOTE_CAN, IDLOTE_CCE = :IDLOTE_CCE, XML_NF = :XML_NF, XML_CANCELADO = :XML_CANCELADO, XML_CCE = :XML_CCE, XML_AUTORIZADO = :XML_AUTORIZADO, STATUS_EXPORTA = :STATUS_EXPORTA, IDLOTE_ENV = :IDLOTE_ENV, RECIBO_NFE = :RECIBO_NFE, CUPONS_NFE = :CUPONS_NFE, INDIE_DEST = :INDIE_DEST, NFE_REF = :NFE_REF, ENTRADA_NF = :ENTRADA_NF, DESCONTO_PER_NF = :DESCONTO_PER_NF, QUANT_PARCELAS = :QUANT_PARCELAS, VALOR_TOTAL_PARCELAS = :VALOR_TOTAL_PARCELAS, DIFERENCA_PARCELAS = :DIFERENCA_PARCELAS, INDPAG_NF = :INDPAG_NF, IDDEST_NF = :IDDEST_NF, FINALIDADE_NF = :FINALIDADE_NF, INDFINAL_NF = :INDFINAL_NF, INDPRESENCA_NF = :INDPRESENCA_NF, CODIGO_CNF = :CODIGO_CNF, XML_INUTILIZADO = :XML_INUTILIZADO, PROTOCOLO_INUTILIZACAO = :PROTOCOLO_INUTILIZACAO, DHRECEBTO_INUTILIZACAO = :DHRECEBTO_INUTILIZACAO, NAT_OPERACAO = :NAT_OPERACAO, STATUS_AUTORIZADA = :STATUS_AUTORIZADA, STATUS_DENEGADA = :STATUS_DENEGADA, TIPO_ES_NF = :TIPO_ES_NF, ICMSDESON_NF = :ICMSDESON_NF, FCPUFDEST_NF = :FCPUFDEST_NF, ICMSUFDEST_NF = :ICMSUFDEST_NF, ICMSUFREMET_NF = :ICMSUFREMET_NF, VALOR_II_NF = :VALOR_II_NF, VALOR_PIS_NF = :VALOR_PIS_NF, VALOR_COFINS_NF = :VALOR_COFINS_NF, VALOR_TRIB_NF = :VALOR_TRIB_NF, BC_ISS_NF = :BC_ISS_NF, VALOR_ISS_NF = :VALOR_ISS_NF, VALOR_PIS_ISS_NF = :VALOR_PIS_ISS_NF, VALOR_COFINS_ISS_NF = :VALOR_COFINS_ISS_NF, DTCOMP_ISS_NF = :DTCOMP_ISS_NF, VALOR_DED_ISS_NF = :VALOR_DED_ISS_NF, VALOR_OUTRO_ISS_NF = :VALOR_OUTRO_ISS_NF, DESCINCOND_ISS_NF = :DESCINCOND_ISS_NF, DESCCOND_ISS_NF = :DESCCOND_ISS_NF, REGTRIB_ISS_NF = :REGTRIB_ISS_NF, VALOR_RETPIS_NF = :VALOR_RETPIS_NF, VALOR_RETCOFINS = :VALOR_RETCOFINS, VALOR_RETCSLL = :VALOR_RETCSLL, BASE_IRRF_NF = :BASE_IRRF_NF, VALOR_IRRF = :VALOR_IRRF, BASE_RETPREV = :BASE_RETPREV, VALOR_RETPREV = :VALOR_RETPREV, INF_AD_FISCO = :INF_AD_FISCO, QR_CODE = :QR_CODE, CHAVE_ORIGINAL = :CHAVE_ORIGINAL
WHERE
  COD_NF = :Old_COD_NF
how would the update sql with the alias V even?
I already unset setfieldsReadOnly, and still does not update the alias "V"

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: Update more than one table firebird unidac

Post by ViktorV » Tue 27 Feb 2018 13:46

You should write the required query for updating all the data and specify it in the TUniQuery.SQLUpdate property.
Example:

Code: Select all

  UniQuery.SQL.Text := 'select emp.empno, emp.ename, emp.job, dept.deptno, dept.dname  from emp inner join dept on (dept.deptno = emp.deptno)';
  UniQuery.SQLUpdate.Text := 
    'EXECUTE BLOCK (Old_EMPNO INTEGER = :Old_EMPNO, EMPNO INTEGER = :EMPNO, ENAME VARCHAR(255) = :ENAME, JOB VARCHAR(255)= :JOB, Old_DEPTNO INTEGER = :Old_DEPTNO, DEPTNO INTEGER = :DEPTNO, DNAME VARCHAR(255) = :DNAME) ' +
    'AS ' +
    'BEGIN ' +
    'UPDATE EMP '+
    'SET '+
      'EMPNO = :EMPNO, ENAME = :ENAME, JOB = :JOB '+
    'WHERE '+
      'EMPNO = :Old_EMPNO; '+
    'UPDATE DEPT '+
    'SET '+
      'DEPTNO = :DEPTNO, DNAME = :DNAME '+
    'WHERE '+
      'DEPTNO = :Old_DEPTNO; '+
    'END';
You can write the required query based on the example above.

gss200610
Posts: 35
Joined: Mon 23 May 2016 22:29

Re: Update more than one table firebird unidac

Post by gss200610 » Tue 27 Feb 2018 13:48

right, and how would I put this straight into the sql property of uniquery?

gss200610
Posts: 35
Joined: Mon 23 May 2016 22:29

Re: Update more than one table firebird unidac

Post by gss200610 » Tue 27 Feb 2018 17:29

the temporary solution I found based on firedac. as the join fields that are not accepting update are few, I will treat the event update record, correct me if it is wrong, or there is a better way to handle the onupdate event.
what would be the best way to handle it, or rather how would the code look like the correct form in the event?

procedure TForm1.UniQuery1UpdateRecord(DataSet: TDataSet;
UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
begin
if UpdateKind = ukModify then
begin
UniConnection1.ExecSQL('UPDATE VENDAS SET R04_NOME_CLIENTE = :CLI WHERE COD_VEN = :CODVEN',
[UniQuery1R04_NOME_CLIENTE.AsString, UniQuery1COD_VEN.AsInteger] );
end;
UpdateAction := uaApplied;
end;

gss200610
Posts: 35
Joined: Mon 23 May 2016 22:29

Re: Update more than one table firebird unidac

Post by gss200610 » Tue 27 Feb 2018 20:06

how to use the onupdaterecord event to update a table checking if a certain table was written correctly using cached updates in this check table?
to be clearer, in the onupdaterecord event of the note table, I need to check if the data was saved and sent to the bank in order to update the sales table

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: Update more than one table firebird unidac

Post by ViktorV » Wed 28 Feb 2018 14:35

When executing the code you specified, the VENDAS table will be updated upon execution of the ApplyUpdates method, i.e. before you save the changes on the server.
To solve your problem, we suggest using the recommendations mentioned above: create a query for updating all the data and specify it in the UniQuery.SQLUpdate.Text property. You can do this either in the design-time or run-time.
If the SQLInsert, SQLUpdate, SQLDelete, SQLRefresh properties are not empty, for example, generated in design-time or set manually, UniDAC will use SQL query specified in this property. If the property is set to an empty string, UniDAC will automatically generate the necessary SQL queries when executing the corresponding operations.

gss200610
Posts: 35
Joined: Mon 23 May 2016 22:29

Re: Update more than one table firebird unidac

Post by gss200610 » Wed 28 Feb 2018 15:00

right, I tried using 2 commands updates example:
update xxx set;
update aaa set;
as I have seen in some post here, but for firebird, there is always a sql statement error.
why imagine having to generate a manual execute block with more than 100 fields to populate the updatesql property, is there an alternative way that the own query generates the statement, or do I put it without using execute bock?

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: Update more than one table firebird unidac

Post by ViktorV » Wed 28 Feb 2018 15:28

This error is returned by Firebird, because the server does not allow you to execute the queries you specified without using the execute block. You can verify this by running the queries you have provided using the standard means, for example, isql.exe Firebird utility.
Therefore, you should use the queries you specified in the execute block structure.

gss200610
Posts: 35
Joined: Mon 23 May 2016 22:29

Re: Update more than one table firebird unidac

Post by gss200610 » Wed 28 Feb 2018 15:54

summarizing, with firebird only using execute blcock and putting the two sql statements...

gss200610
Posts: 35
Joined: Mon 23 May 2016 22:29

Re: Update more than one table firebird unidac

Post by gss200610 » Wed 28 Feb 2018 17:40

can I use this query event: TCustomDADataSet.AfterUpdateExecute to write to another table?

Is this event triggered if the query successfully executes the update?

which uniquery event do I know if the record has already been committed in the database?

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: Update more than one table firebird unidac

Post by ViktorV » Thu 01 Mar 2018 11:54

To solve the issue, you should use the TUniTransaction.OnCommitRetaining (TUniTransaction.OnCommit) event handlers: https://devart.com/unidac/docs/index.ht ... aining.htm, https://devart.com/unidac/docs/index.ht ... commit.htm

Post Reply