Como criar uma função para criar uma tabela temporaria e dar INSERT nela atraves de um SELECT

9 respostas
J

Olá pessoal,

Tenho um relatório com o sql abaxo, porém ele é muito pesado e quando mando gerar esse relatório pelo sistema, ele não gera.
A minha estratégia para resolver esse problema é criar uma função com os seguintes passos:

1º passo: Criar uma tabela temporária (tabelaTemporaria) cujas colunas correspondem aos campos do SELECT do sql abaixo;

2º passo:  um INSERT nessa tabela temporária com os dados colhidos pelo sql abaixo;

3º passo: O sql do relatório muda para SELECT * FROM tabelaTemporaria;

4º passo: Zerar a tabela temporaria.

A pergunta é: como faço essa função??? rsrs

SELECT
     solicitacao."soli_pk_id" AS solicitacao_soli_pk_id,
     solicitacao."soli_data_solicitacao" AS solicitacao_soli_data_solicitacao,
     servicosdimat."smat_nome" AS servicosdimat_smat_nome,
     servicosdimat."smat_preco" AS servicosdimat_smat_preco,
     servicosdimee."smee_nome" AS servicosdimee_smee_nome,
     servicosdimee."smee_preco" AS servicosdimee_smee_preco,
     servicosditalq."salq_nome" AS servicosditalq_salq_nome,
     servicosditalq."salq_preco" AS servicosditalq_salq_preco,
     servicosnit."snit_servico" AS servicosnit_snit_servico,
     servicosnit."snit_preco" AS servicosnit_snit_preco,
     funcionario."func_nome" AS funcionario_func_nome,
     laboratorio."labo_nome" AS laboratorio_labo_nome,
     divisoes."divi_nome" AS divisoes_divi_nome,
     clientefisica."clfi_nome" AS clientefisica_clfi_nome,
     clientefisica."clfi_fone" AS clientefisica_clfi_fone
FROM 
  sigi.clientefisica, 
  sigi.solicitacao, 
  sigi.servicosdimat, 
  sigi.servicosdimee, 
  sigi.servicosditalq, 
  sigi.servicosnit, 
  sigi.funcionario, 
  sigi.divisoes, 
  sigi.laboratorio, 
  sigi.intermediaria
  WHERE 
  ( solicitacao.soli_fk_divisoes1_id = divisoes.divi_pk_id OR
  solicitacao.soli_fk_divisoes2_id = divisoes.divi_pk_id OR
  solicitacao.soli_fk_divisoes3_id = divisoes.divi_pk_id OR
  solicitacao.soli_fk_divisoes4_id = divisoes.divi_pk_id OR
  solicitacao.soli_fk_divisoes5_id = divisoes.divi_pk_id ) AND
  solicitacao.soli_fk_funcionario_cadastrou_id = funcionario.func_pk_id AND
  solicitacao.soli_fk_cliente_fisica_id = clientefisica.clfi_pk_id AND
  ( servicosdimat.smat_fk_laboratorio_id = laboratorio.labo_pk_id OR
  servicosdimee.smee_fk_laboratorio_id = laboratorio.labo_pk_id OR
  servicosditalq.salq_fk_laboratorio_id = laboratorio.labo_pk_id OR
  servicosnit.snit_fk_laboratorio_id = laboratorio.labo_pk_id ) AND
  intermediaria.inte_codigo_solicitacao = solicitacao.soli_pk_id AND
  ( intermediaria.inte_fk_servico_dimat_id = servicosdimat.smat_pk_id OR
  intermediaria.inte_fk_servico_dimee_id = servicosdimee.smee_pk_id OR
  intermediaria.inte_fk_servico_ditalq_id = servicosditalq.salq_pk_id OR
  intermediaria.inte_fk_servico_nit_id = servicosnit.snit_pk_id);

9 Respostas

E

O ideal seria você aperfeiçoar este seu select utilizando inner join fazendo a consulta pelas chaves primárias de suas tabelas de preferência que estás não sejam do tipo char/varchar desta forma que você está fazendo o select é muito custo para o banco de dados pesquisar os registros.

F

Concordo, melhore está consulta que acredito que seja o caminho mais fácil e útil.

J

Os INNER JOIN estão dentro do WHERE. É outra forma de fazê-lo, que inclusivamente é mais legível.

J

De acordo com essa estratégia, meu sql é simplificado para SELECT * FROM temporaria; e mais otimizado que isso não dá.
No entanto, queria saber como faço um INSERT com o retorno de um SELECT.

Estava tentando o seguinte código, mas ele gera um erro de sintaxe bem na linha 27:

CREATE TABLE sigi.temporaria 
(
temp_pk_id serial NOT NULL,
temp_soli_pk_id integer,
temp_soli_data_solicitacao date,
temp_smat_nome character varying,
temp_smat_preco numeric(19,2),
temp_smee_nome character varying,
temp_smee_preco numeric(19,2),
temp_salq_nome character varying,
temp_salq_preco numeric(19,2),
temp_snit_servico character varying,
temp_snit_preco numeric(19,2),
temp_func_nome character varying,
temp_labo_nome character varying,
temp_divi_nome character varying,
temp_clfi_nome character varying,
temp_clfi_fone character varying,
CONSTRAINT temporaria_pkey PRIMARY KEY (temp_pk_id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE sigi.temporaria OWNER TO root;

INSERT INTO sigi.temporaria VALUES (
SELECT
     solicitacao."soli_pk_id" AS solicitacao_soli_pk_id,
     solicitacao."soli_data_solicitacao" AS solicitacao_soli_data_solicitacao,
     servicosdimat."smat_nome" AS servicosdimat_smat_nome,
     servicosdimat."smat_preco" AS servicosdimat_smat_preco,
     servicosdimee."smee_nome" AS servicosdimee_smee_nome,
     servicosdimee."smee_preco" AS servicosdimee_smee_preco,
     servicosditalq."salq_nome" AS servicosditalq_salq_nome,
     servicosditalq."salq_preco" AS servicosditalq_salq_preco,
     servicosnit."snit_servico" AS servicosnit_snit_servico,
     servicosnit."snit_preco" AS servicosnit_snit_preco,
     funcionario."func_nome" AS funcionario_func_nome,
     laboratorio."labo_nome" AS laboratorio_labo_nome,
     divisoes."divi_nome" AS divisoes_divi_nome,
     clientefisica."clfi_nome" AS clientefisica_clfi_nome,
     clientefisica."clfi_fone" AS clientefisica_clfi_fone
FROM 
  sigi.clientefisica, 
  sigi.solicitacao, 
  sigi.servicosdimat, 
  sigi.servicosdimee, 
  sigi.servicosditalq, 
  sigi.servicosnit, 
  sigi.funcionario, 
  sigi.divisoes, 
  sigi.laboratorio, 
  sigi.intermediaria
  WHERE 
  ( solicitacao.soli_fk_divisoes1_id = divisoes.divi_pk_id OR
  solicitacao.soli_fk_divisoes2_id = divisoes.divi_pk_id OR
  solicitacao.soli_fk_divisoes3_id = divisoes.divi_pk_id OR
  solicitacao.soli_fk_divisoes4_id = divisoes.divi_pk_id OR
  solicitacao.soli_fk_divisoes5_id = divisoes.divi_pk_id ) AND
  solicitacao.soli_fk_funcionario_cadastrou_id = funcionario.func_pk_id AND
  solicitacao.soli_fk_cliente_fisica_id = clientefisica.clfi_pk_id AND
  ( servicosdimat.smat_fk_laboratorio_id = laboratorio.labo_pk_id OR
  servicosdimee.smee_fk_laboratorio_id = laboratorio.labo_pk_id OR
  servicosditalq.salq_fk_laboratorio_id = laboratorio.labo_pk_id OR
  servicosnit.snit_fk_laboratorio_id = laboratorio.labo_pk_id ) AND
  intermediaria.inte_codigo_solicitacao = solicitacao.soli_pk_id AND
  ( intermediaria.inte_fk_servico_dimat_id = servicosdimat.smat_pk_id OR
  intermediaria.inte_fk_servico_dimee_id = servicosdimee.smee_pk_id OR
  intermediaria.inte_fk_servico_ditalq_id = servicosditalq.salq_pk_id OR
  intermediaria.inte_fk_servico_nit_id = servicosnit.snit_pk_id);
);
SELECT * FROM temporaria;
J

Galera, acabei de resolver o problema \o/\o/

No sql, onde tem CREATE TABLE sigi.temporaria
tem que apagar a PK temp_soli_pk_id integer,porque os campos da temporaria deve corresponder aos campos do SELECT e nao existe um campo no SELECT que corresponde
a temp_soli_pk_id integer, Consequentemente deve-se apagar CONSTRAINT temporaria_pkey PRIMARY KEY (temp_pk_id)

Onde tem INSERT INTO sigi.temporaria VALUES (, basta tirar a palavra “VALUES” e pronto, funcionou perfeitamente:

CREATE TABLE sigi.temporaria 
(
temp_soli_pk_id integer,
temp_soli_data_solicitacao date,
temp_smat_nome character varying,
temp_smat_preco numeric(19,2),
temp_smee_nome character varying,
temp_smee_preco numeric(19,2),
temp_salq_nome character varying,
temp_salq_preco numeric(19,2),
temp_snit_servico character varying,
temp_snit_preco numeric(19,2),
temp_func_nome character varying,
temp_labo_nome character varying,
temp_divi_nome character varying,
temp_clfi_nome character varying,
temp_clfi_fone character varying
)
WITH (
  OIDS=FALSE
);
ALTER TABLE sigi.temporaria OWNER TO root;

INSERT into sigi.temporaria (
SELECT
     solicitacao."soli_pk_id" AS solicitacao_soli_pk_id,
     solicitacao."soli_data_solicitacao" AS solicitacao_soli_data_solicitacao,
     servicosdimat."smat_nome" AS servicosdimat_smat_nome,
     servicosdimat."smat_preco" AS servicosdimat_smat_preco,
     servicosdimee."smee_nome" AS servicosdimee_smee_nome,
     servicosdimee."smee_preco" AS servicosdimee_smee_preco,
     servicosditalq."salq_nome" AS servicosditalq_salq_nome,
     servicosditalq."salq_preco" AS servicosditalq_salq_preco,
     servicosnit."snit_servico" AS servicosnit_snit_servico,
     servicosnit."snit_preco" AS servicosnit_snit_preco,
     funcionario."func_nome" AS funcionario_func_nome,
     laboratorio."labo_nome" AS laboratorio_labo_nome,
     divisoes."divi_nome" AS divisoes_divi_nome,
     clientefisica."clfi_nome" AS clientefisica_clfi_nome,
     clientefisica."clfi_fone" AS clientefisica_clfi_fone
FROM 
  sigi.clientefisica, 
  sigi.solicitacao, 
  sigi.servicosdimat, 
  sigi.servicosdimee, 
  sigi.servicosditalq, 
  sigi.servicosnit, 
  sigi.funcionario, 
  sigi.divisoes, 
  sigi.laboratorio, 
  sigi.intermediaria
  WHERE 
  ( solicitacao.soli_fk_divisoes1_id = divisoes.divi_pk_id OR
  solicitacao.soli_fk_divisoes2_id = divisoes.divi_pk_id OR
  solicitacao.soli_fk_divisoes3_id = divisoes.divi_pk_id OR
  solicitacao.soli_fk_divisoes4_id = divisoes.divi_pk_id OR
  solicitacao.soli_fk_divisoes5_id = divisoes.divi_pk_id ) AND
  solicitacao.soli_fk_funcionario_cadastrou_id = funcionario.func_pk_id AND
  solicitacao.soli_fk_cliente_fisica_id = clientefisica.clfi_pk_id AND
  ( servicosdimat.smat_fk_laboratorio_id = laboratorio.labo_pk_id OR
  servicosdimee.smee_fk_laboratorio_id = laboratorio.labo_pk_id OR
  servicosditalq.salq_fk_laboratorio_id = laboratorio.labo_pk_id OR
  servicosnit.snit_fk_laboratorio_id = laboratorio.labo_pk_id ) AND
  intermediaria.inte_codigo_solicitacao = solicitacao.soli_pk_id AND
  ( intermediaria.inte_fk_servico_dimat_id = servicosdimat.smat_pk_id OR
  intermediaria.inte_fk_servico_dimee_id = servicosdimee.smee_pk_id OR
  intermediaria.inte_fk_servico_ditalq_id = servicosditalq.salq_pk_id OR
  intermediaria.inte_fk_servico_nit_id = servicosnit.snit_pk_id)
);
SELECT * FROM sigi.temporaria;
P

JonRocha:
De acordo com essa estratégia, meu sql é simplificado para SELECT * FROM temporaria; e mais otimizado que isso não dá.

Continuas a ter de fazer o SELECT para introduzir os dados na tabela temporária. Não vais optimizar nada…

J

É verdade… rs

E

TALVEZ dependendo da situação seria melhor você criar uma tabela normalizada de acordo com o seu relatório, e no caso ao efeturar uma operação já inserir campos normalizados em sua tabela de relatórios isso evitária o retrabalho que você está tendo, mas no caso duplicaria os inserts do sistema.

J

Compreendo…

Criado 21 de março de 2011
Ultima resposta 22 de mar. de 2011
Respostas 9
Participantes 4