Update using values contained in another table

2

How can I do an update on a table by setting the value of a field with the same value contained in another table for all records?

I have a 'product' table and a 'mov product' table. I want to update the information related to the cost price in the 'product' table with the same value contained in the 'mov product' table.

tabela 'produto'
codproduto
vlrprecocusto

tabela 'movproduto'
codproduto
vlrprecocusto

I tried some ways and I did not succeed. Example of how you were trying:

update produto p 
inner join movproduto m on m.codproduto = p.codproduto
    set p.vlrprecocusto = m.vlrprecocusto;

This sql returns the following error:

token unknown - line 2, column 5
inner

I'm using firebird 2.5

    
asked by anonymous 29.06.2018 / 14:06

2 answers

0

Try the following:

update produto p
set
  p.vlrprecocusto = (select 
                       m.vlrprecocusto
                     from movproduto m 
                     where 
                       (m.codproduto = p.codproduto))

Explanation

For each record in the "product" table, the same code record will be selected in the table "mov product"; The value of the "vlrprecocusto" field of the "mov product" table will be saved in the "vlrprecocusto" field of the "product" table.

Attention

  • If no record with the same code is found in the table "mov product" will be written NULL in the "product"; If you want to avoid NULL, you can use the COALESCE function, but if you want "product" without a "product" to not change, then a condition must be included in the WHERE clause to affect only records that exist in the "mov product" / p>

  • If there are duplicate records with the same "product code" in the "mov product" table, the error "multiple rows in singleton select" will occur. To solve this you can use "FIRST 1" in the sub-select or use GROUP BY with the AVG function in the "vlrprecocusto" field of the table "movproduto".

Any questions, please ask.

    
30.06.2018 / 07:14
2

Unfortunately, FIREBIRD does not accept update with inners ...

You would have to do something +/- so

update produto set vlrprecocusto = valor;
  where codproduto in (select codproduto 
                         from produto
                        inner join movproduto m on m.codproduto = p.codproduto)

Note: Check my update before running it so as not to damage your data if I have put some wrong information.

Edited

I'm sorry, in the example above I only showed the structure without paying attention to the fields, it would serve for you to set a fixed value for the codecode field ...

In case to make the update you want it would have to do so

EXECUTE BLOCK AS
  DECLARE VARIABLE iCodProduto INTEGER;
  DECLARE VARIABLE nValorCusto NUMERIC(18,4);
BEGIN
  FOR select p.codproduto 
            ,m.vlrprecocusto
        from      produto    p
       inner join movproduto m on m.codproduto = p.codproduto INTO :iCodProduto, :nValorCusto DO
  BEGIN
    update produto set vlrprecocusto = :nValorCusto where codproduto = :iCodProduto;
  END
END;

If you are running this script on a project you are doing, see if the component you are using accepts execute block , for example, delphi 7's TIBQuery would not run this script, but if it is running directly on the database, There it runs smoothly.

    
29.06.2018 / 14:12