Java + Firebird

4 respostas Resolvido
java
D

Estou tentando criar um insert em uma base já criada quando executa essa linha

PreparedStatement pst = c.prepareStatement(“insert into PRODUTO ( ID, TIPO, FK_PRODUTO_SUBGRUPO, FK_PRODUTO_UNIDADE, DESCRICAO, STATUS, OBSERVACAO, ESTOQUE_MAXIMO, ITENS_CAIXA, FK_CLASSIFICACAO_FISCAL, DATA_CADASTRO, FK_PRODUTO_MARCA, SUBSTITUICAO_TRIB_RETIDO, REFERENCIA, DESCONTO_MAXIMO, PESO_BRUTO, PESO_LIQUIDO, CUSTO, FK_LISTA_SERVICO_ITEM, FK_PRODUTO_COR, FK_PRODUTO_TAMANHO, CUSTO_MEDIO, CUSTO_DOLAR, FK_PRODUTO_UNIDADE_2, CUBAGEM, CUSTO_ULTIMO, PERCENTUAL_VENDA_SERVICO, PORCAO_POR_PESSOA, TEMPO_PREPARO, QUANTIDADE, GUARNICOES, FK_PRODUTO_ESPECIFICACAO, ISS_PERCENTUAL, CODIGO_PESO, UTILIZA_BALANCA_PESO, ARREDONDAMENTO_TRUNCAMENTO, PRODUCAO_PROPRIA_TERCEIROS, SITE_UTILIZA, FK_CLASSIFICACAO_SEM_SIMILAR, FK_CLASSIFICACAO_IPI, EMBALAGEM_QUANT_ITENS , VALIDADE_DIAS , VALIDADE_TIPO, VALOR_NUTRICIONAL , FK_PRODUTO_COLECAO, TIPO_REFEICAO, PRODUCAO_STATUS, FK_CENTRO_CUSTO , FK_CEST , IMPRIME_COZINHA , FATOR_CONVERSAO_TIPO , IND_ESCALA_TIPO , STATUS_MOBILE ) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? )”);

estou tendo o seguinte erro GDS Exception. 335544359. attempted update of read-only column pesquisei sobre o erro e se refere a uma coluna que esta com status somente de leitura mas tentei efetuar o insert com comando sql e foi normalmente .
Aguem poderia me ajudar

4 Respostas

T

Algum desses campos é calculado (computed by)? Está preenchendo as colunas que são chaves estrangeiras com valores válidos (que existem nas tabelas referenciadas) ? Há alguma trigger nessa tabela? Poste a estrutura da tabela e os dados que você está tentando inserir em cada campo.

Abraço.

D

Explicar oq acontece temos esse sistema que foi criado por um programador contratado. Infelizmente ele veio a falecer no mês passado. Estamos criando um novo programa em java e ir migrando pouco a pouco começamos com o cadastro de produto a descrição

CREATE DOMAIN “D_ENUMERADO” AS SMALLINT

DEFAULT 0 NOT NULL;

CREATE DOMAIN “D_MOEDA_ESTRANGEIRA” AS NUMERIC(18, 6)

DEFAULT 0 NOT NULL;

CREATE DOMAIN “D_PERCENTUAL” AS NUMERIC(15, 5)

DEFAULT 0 NOT NULL;

CREATE DOMAIN “D_PESO” AS NUMERIC(15, 5)

DEFAULT 0

CHECK (VALUE >= 0) NOT NULL;

CREATE DOMAIN “D_QUANTIDADE” AS NUMERIC(15, 2)

DEFAULT 0 NOT NULL;

CREATE DOMAIN “D_SIM_NAO” AS CHAR(1)

DEFAULT 'N’

CHECK (VALUE IN (‘S’,‘N’)) NOT NULL;

CREATE DOMAIN “D_VALOR_EXTENDIDO_3” AS NUMERIC(15, 3)

DEFAULT 0 NOT NULL;

CREATE DOMAIN “D_VALOR_PRODUTO” AS NUMERIC(15, 5)

DEFAULT 0 NOT NULL;

/* Table: PRODUTO, Owner: SYSDBA */

CREATE TABLE “PRODUTO”

(

“ID”	 INTEGER NOT NULL,

“TIPO”	 SMALLINT,

“FK_PRODUTO_SUBGRUPO”	 INTEGER,

“FK_PRODUTO_UNIDADE”	 INTEGER,

“DESCRICAO”	 VARCHAR(120),

“STATUS”	 INTEGER,

“OBSERVACAO”	 VARCHAR(1000),

“ESTOQUE_MAXIMO”	 D_QUANTIDADE  DEFAULT 0,

“FATOR_CONVERSAO”	 NUMERIC(18,5),

“FK_CLASSIFICACAO_FISCAL”	 INTEGER,

“DATA_CADASTRO”	 DATE,

“FK_PRODUTO_MARCA”	 INTEGER,

“SUBSTITUICAO_TRIB_RETIDO”	 D_SIM_NAO  DEFAULT ‘N’,

“REFERENCIA”	 VARCHAR(50),

“DESCONTO_MAXIMO”	 D_PERCENTUAL  DEFAULT 0,

“PESO_BRUTO”	 D_PESO  DEFAULT 0,

“PESO_LIQUIDO”	 D_PESO  DEFAULT 0,

“CUSTO”	 D_VALOR_PRODUTO  DEFAULT 0,

“FK_LISTA_SERVICO_ITEM”	 INTEGER,

“FK_PRODUTO_COR”	 INTEGER,

“FK_PRODUTO_TAMANHO”	 INTEGER,

“CUSTO_MEDIO”	 D_VALOR_PRODUTO  DEFAULT 0,

“CUSTO_DOLAR”	 D_MOEDA_ESTRANGEIRA  DEFAULT 0,

“FK_PRODUTO_UNIDADE_2”	 INTEGER,

“CUBAGEM”	 D_VALOR_EXTENDIDO_3  DEFAULT 0,

“CUSTO_ULTIMO”	 D_VALOR_PRODUTO  DEFAULT 0,

“PERCENTUAL_VENDA_SERVICO”	 D_PERCENTUAL  DEFAULT 0,

“PORCAO_POR_PESSOA”	 INTEGER,

“TEMPO_PREPARO”	 TIME,

“GUARNICOES”	 INTEGER,

“FK_PRODUTO_ESPECIFICACAO”	 INTEGER,

“ISS_PERCENTUAL”	 D_PERCENTUAL  DEFAULT 0,

“CODIGO_PESO”	 INTEGER,

“UTILIZA_BALANCA_PESO”	 D_SIM_NAO  DEFAULT ‘N’,

“ARREDONDAMENTO_TRUNCAMENTO”	 SMALLINT,

“PRODUCAO_PROPRIA_TERCEIROS”	 SMALLINT,

“SITE_UTILIZA”	 D_SIM_NAO  DEFAULT ‘N’,

“FK_CLASSIFICACAO_SEM_SIMILAR”	 INTEGER,

“FK_CLASSIFICACAO_IPI”	 INTEGER,

“EMBALAGEM_QUANT_ITENS”	 D_QUANTIDADE  DEFAULT 0,

“VALIDADE_DIAS”	 SMALLINT,

“VALIDADE_TIPO”	 SMALLINT,

“VALOR_NUTRICIONAL”	 D_VALOR_EXTENDIDO_3  DEFAULT 0,

“FK_PRODUTO_COLECAO”	 INTEGER,

“TIPO_REFEICAO”	 D_ENUMERADO  DEFAULT 0,

“PRODUCAO_STATUS”	 D_ENUMERADO  DEFAULT 0,

“FK_CENTRO_CUSTO”	 INTEGER,

“FK_CEST”	 INTEGER,

“QUANTIDADE”	 D_QUANTIDADE  DEFAULT 0,

“IMPRIME_COZINHA”	 D_SIM_NAO  DEFAULT ‘N’,

“FATOR_CONVERSAO_TIPO”	 D_ENUMERADO  DEFAULT 0,

“ITENS_CAIXA”	 COMPUTED BY (   CASE WHEN FATOR_CONVERSAO_TIPO = 0 /<em>TpFatorMultiplicacao</em>/

THEN FATOR_CONVERSAO

ELSE CAST( (1 / FATOR_CONVERSAO) AS Numeric(18,5) )

END ),

“IND_ESCALA_TIPO”	 D_ENUMERADO  DEFAULT 0,

“IND_ESCALA_CNPJ”	 VARCHAR(21),

“IND_ESCALA_BENEFICIO_COD”	 VARCHAR(10),

“ORIGEM_PRODUTO”	 VARCHAR(50),

“DATA_HORA_DIGITACAO”	 TIMESTAMP,

“FK_USUARIO_DIGITACAO”	 INTEGER,

“STATUS_MOBILE”	 D_ENUMERADO  DEFAULT 0,

CONSTRAINT “PK_PRODUTO” PRIMARY KEY (“ID”),

CONSTRAINT “UNQ_PRODUTO_1” UNIQUE (“CODIGO_PESO”)

);

/* Index definitions for PRODUTO */

CREATE UNIQUE INDEX “IND_PRODUTO_1” ON “PRODUTO”(“REFERENCIA”);

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_1” FOREIGN KEY (“FK_PRODUTO_UNIDADE”) REFERENCES “PRODUTO_UNIDADE” (“ID”);

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_10” FOREIGN KEY (“FK_PRODUTO_TAMANHO”) REFERENCES “PRODUTO_TAMANHO” (“ID”);

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_11” FOREIGN KEY (“FK_PRODUTO_UNIDADE_2”) REFERENCES “PRODUTO_UNIDADE” (“ID”);

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_13” FOREIGN KEY (“FK_PRODUTO_ESPECIFICACAO”) REFERENCES “PRODUTO_ESPECIFICACAO” (“ID”);

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_14” FOREIGN KEY (“FK_CLASSIFICACAO_SEM_SIMILAR”) REFERENCES “CLASSIFICACAO_SEM_SIMILAR” (“ID”);

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_15” FOREIGN KEY (“FK_CLASSIFICACAO_IPI”) REFERENCES “CLASSIFICACAO_FISCAL_IPI” (“ID”);

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_16” FOREIGN KEY (“FK_PRODUTO_COLECAO”) REFERENCES “PRODUTO_COLECAO” (“ID”);

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_17” FOREIGN KEY (“FK_CENTRO_CUSTO”) REFERENCES “CAD_CONTAS_ITEM” (“ID”);

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_18” FOREIGN KEY (“FK_CEST”) REFERENCES “CEST” (“ID”) ON UPDATE CASCADE;

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_19” FOREIGN KEY (“FK_USUARIO_DIGITACAO”) REFERENCES “SYS_USUARIO” (“ID”);

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_2” FOREIGN KEY (“FK_PRODUTO_SUBGRUPO”) REFERENCES “PRODUTO_SUBGRUPO” (“ID”);

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_4” FOREIGN KEY (“FK_CLASSIFICACAO_FISCAL”) REFERENCES “CLASSIFICACAO_FISCAL” (“ID”);

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_7” FOREIGN KEY (“FK_PRODUTO_MARCA”) REFERENCES “PRODUTO_MARCA” (“ID”);

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_8” FOREIGN KEY (“FK_LISTA_SERVICO_ITEM”) REFERENCES “LISTA_SERVICO_ITEM” (“ID”) ON UPDATE CASCADE;

ALTER TABLE “PRODUTO” ADD CONSTRAINT “FK_PRODUTO_9” FOREIGN KEY (“FK_PRODUTO_COR”) REFERENCES “PRODUTO_COR” (“ID”);

SET TERM ^ ;

/* Triggers only will work for SQL triggers */

CREATE TRIGGER “PRODUTO_AU0” FOR "PRODUTO"

ACTIVE AFTER UPDATE POSITION 0

AS

BEGIN

IF(USER = ‘SYSDBA’) THEN

IF (OLD.CUSTO <> NEW.CUSTO) THEN

INSERT INTO PRODUTO_VALOR_COMPRA (ID, FK_PRODUTO, DATA_HORA, VALOR, FK_USUARIO)

VALUES ((Select result from SP_GET_GENERATOR(‘GEN_PRODUTO_VALOR_COMPRA’)), <a href="http://OLD.ID">OLD.ID</a>, current_timestamp, new.CUSTO, rdb$get_context(‘USER_SESSION’, ‘USUARIO_ID’));

END

^
CREATE TRIGGER PRODUTO_AU13 FOR "PRODUTO"

ACTIVE AFTER UPDATE POSITION 13

AS

declare variable ID_CTL_EST INTEGER = 0;

declare variable VENDA      INTEGER = 0;
declare variable CUSTO_MESTRE D_VALOR_PRODUTO = 0;

declare variable CUSTO_ITEM   D_VALOR_PRODUTO = 0;

declare variable OPERACAO     INTEGER      = 0;

declare variable PROD_MESTRE  INTEGER      = 0;

declare variable PROD_ITEM    INTEGER      = 0;

declare variable FATOR_CONV   D_QUANTIDADE = 0;
DECLARE trgrDone VARCHAR(255);

BEGIN

IF (USER <> SYSDBA)

THEN EXIT;

trgrDone = RDB$GET_CONTEXT(‘USER_TRANSACTION’, ‘PRODUTO_AU13’);

IF (trgrDone IS NOT NULL)
THEN EXIT;

IF (OLD.CUSTO <> NEW.CUSTO) THEN
BEGIN
rdb$set_context(‘USER_TRANSACTION’, ‘PRODUTO_AU13’, 1);

--vendo se o produto alterado eh o MESTRE de EstoqueUnificado
SELECT M.ID, M.FK_PRODUTO_MASTER
FROM PRODUTO_CTL_EST M
WHERE M.FK_PRODUTO_MASTER = OLD.ID
AND M.TIPO_CUSTO = 1/*UNIFICADO*/
INTO :ID_CTL_EST, :PROD_MESTRE;
              
--busca o parametro para saber o que atualizar no PRODUTO_PRECO
VENDA = (SELECT ATUALIZA_PRECO_VENDA_AUTOMATICO FROM PARAMETROS);
 
--se n????o for o mestre  verifica se faz parte de algum estoque unificado
if ((ID_CTL_EST IS NULL) OR (ID_CTL_EST = 0)) then
 BEGIN
  --pega as informa????????es necess????rias para atualizar o custo do mestre
  SELECT I.FK_PRODUTO_CTL_EST, 
         I.OPERACAO, 
         I.FATOR_CONVERSAO, 
         M.FK_PRODUTO_MASTER
  FROM PRODUTO_CTL_EST_ITEM I
  INNER JOIN PRODUTO_CTL_EST M ON (M.ID = I.FK_PRODUTO_CTL_EST 
                               AND M.TIPO_CUSTO = 1/*UNIFICADO*/) 
  WHERE I.FK_PRODUTO = OLD.ID
  INTO :ID_CTL_EST, :OPERACAO, :FATOR_CONV, :PROD_MESTRE;  
   
  --se n????o fizer parte de um estoque unificado, exit...
  IF ((ID_CTL_EST IS NULL) OR (ID_CTL_EST = 0)) 
  THEN EXIT;
  
  CUSTO_MESTRE = (CASE 
                  WHEN :OPERACAO = 0 --MULTIPLICACAO (SIM, INVERTE!)
                  THEN (NEW.CUSTO / :FATOR_CONV)
                  ELSE (NEW.CUSTO * :FATOR_CONV) --DIVISAO (SIM, INVERTE!)
                  END); 
        
      
  --faz a opera????????o inversa aqui (transforma a quantidade do item na mestre, para achar o custo)
  UPDATE PRODUTO P 
  SET P.CUSTO = :CUSTO_MESTRE 
  WHERE P.ID =  :PROD_MESTRE;   
  
  --ATUALIZA O PRECO OU A MARGEM DE LUCRO DO PRODUTO MESTRE (APENAS SE O CUSTO FOR DIFERENTE DE 0)
  IF (:CUSTO_MESTRE <> 0) THEN
   BEGIN
    IF (VENDA = 0) 
    THEN /*MARGEM DE LUCRO*/
         UPDATE PRODUTO_PRECO PR 
         SET PR.LUCRO = CAST((((PR.VALOR * 100) / :CUSTO_MESTRE)-100) AS D_VALOR_PRODUTO)
         WHERE (PR.VALOR > 0)
		   AND (PR.FK_PRODUTO = :PROD_MESTRE);
    ELSE /*PRECO DE VENDA*/                         
         UPDATE PRODUTO_PRECO PR 
         SET PR.VALOR = CAST((((PR.LUCRO/100)+1) * :CUSTO_MESTRE) AS D_VALOR_PRODUTO)
         WHERE (PR.FK_PRODUTO = :PROD_MESTRE);
   END
  ELSE --SE O CUSTO FOR 0, ATUALIZA O LUCRO PARA 100... 
         UPDATE PRODUTO_PRECO PR 
         SET PR.LUCRO = 100
         WHERE (PR.FK_PRODUTO = :PROD_MESTRE);
 END
  
--agora com o mestre atualizado, ou se o mestre que foi alterado, atualiza todos os produtos vinculados ???? ele!
FOR SELECT I.FK_PRODUTO_CTL_EST, 
           I.OPERACAO, 
           I.FATOR_CONVERSAO, 
           I.FK_PRODUTO,
           PM.CUSTO         
FROM PRODUTO_CTL_EST_ITEM I
INNER JOIN PRODUTO_CTL_EST M  ON (M.ID = I.FK_PRODUTO_CTL_EST 
                              AND M.TIPO_CUSTO = 1/*UNIFICADO*/) 
INNER JOIN PRODUTO         PM ON (PM.ID = M.FK_PRODUTO_MASTER)
WHERE PM.ID = :PROD_MESTRE
INTO :ID_CTL_EST, :OPERACAO, :FATOR_CONV, :PROD_ITEM, :CUSTO_MESTRE DO 
BEGIN
  CUSTO_ITEM = (CASE 
                WHEN :OPERACAO = 0 --MULTIPLICACAO
                THEN (:CUSTO_MESTRE * :FATOR_CONV)
                ELSE (:CUSTO_MESTRE / :FATOR_CONV) --DIVISAO
                END);
  
  --aqui n????o ???? necess????rio inverter o sinal, visto que o pai que atualiza os itens...
  UPDATE PRODUTO P 
  SET P.CUSTO = :CUSTO_ITEM 
  WHERE P.ID = :PROD_ITEM;  
  
  --ATUALIZA O PRECO OU A MARGEM DE LUCRO DOS PRODUTOS ITENS...
  IF (:CUSTO_ITEM <> 0) THEN
   BEGIN
    IF (VENDA = 0) 
    THEN /*MARGEM DE LUCRO*/
         UPDATE PRODUTO_PRECO PR 
         SET PR.LUCRO = CAST((((PR.VALOR * 100) / :CUSTO_ITEM)-100) AS D_VALOR_PRODUTO)
         WHERE (PR.VALOR > 0)
           AND (PR.FK_PRODUTO = :PROD_ITEM);
    ELSE /*PRECO DE VENDA*/             
     begin            
         UPDATE PRODUTO_PRECO PR 
         SET PR.VALOR = CAST((((PR.LUCRO/100)+1) * :CUSTO_ITEM) AS D_VALOR_PRODUTO)
         WHERE (PR.FK_PRODUTO = :PROD_ITEM);     
     end 
  END
 ELSE --SE O CUSTO FOR 0, ATUALIZA O LUCRO PARA 100... 
      UPDATE PRODUTO_PRECO PR 
         SET PR.LUCRO = 100
         WHERE (PR.FK_PRODUTO = :PROD_ITEM);
END

END

rdb$set_context(‘USER_TRANSACTION’, ‘PRODUTO_AU13’, null);
END
^

CREATE TRIGGER “PRODUTO_AIUD5” FOR "PRODUTO"

ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 5

as

begin

if (inserting)

then  execute procedure SP_SET_CHANGE(‘PRODUTO’,‘ID’,<a href="http://NEW.ID">NEW.ID</a>,‘I’);

if (updating)

then  execute procedure SP_SET_CHANGE(‘PRODUTO’,‘ID’,<a href="http://NEW.ID">NEW.ID</a>,‘U’);

if (deleting)

then  execute procedure SP_SET_CHANGE(‘PRODUTO’,‘ID’,<a href="http://OLD.ID">OLD.ID</a>,‘D’);

end

^
CREATE TRIGGER “PRODUTO_AIUD8” FOR "PRODUTO"

ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 8

as

begin

if (inserting)

then  execute procedure SP_SET_CHANGE_TABLET(‘PRODUTO’,‘ID’,<a href="http://NEW.ID">NEW.ID</a>,‘I’);

if (updating)

then  execute procedure SP_SET_CHANGE_TABLET(‘PRODUTO’,‘ID’,<a href="http://NEW.ID">NEW.ID</a>,‘U’);

if (deleting)

then  execute procedure SP_SET_CHANGE_TABLET(‘PRODUTO’,‘ID’,<a href="http://OLD.ID">OLD.ID</a>,‘D’);

end

^

COMMIT WORK ^
SET TERM ;^

T
Solucao aceita

Note que o campo ITENS_CAIXA é calculado (computed by). Campos calculados não precisam ser passados no insert, eles são preenchidos automaticamente (seu valor é calculado com base em alguma fórmula ou outro campo).

Tire esse campo do insert, e tire também a interrogação correspondente e o valor que deve estar sendo passado para ele em algum ponto logo depois.

As triggers não parecem ter influência nesse problema, mas você pode desabilitá-las para testar. Mas faça isso numa base separada, de homologação, para evitar inconsistência de dados. Não esqueça de habilitá-las posteriormente.

Abraço.

D

Obrigado vou testar amanha sinceramente não entendo nada de banco so o basico mesmo

Criado 21 de março de 2018
Ultima resposta 22 de mar. de 2018
Respostas 4
Participantes 2