Resumo: GaussDB (DWS) evoluiu do Postgres.Como o Postgres, se uma tabela é referenciada por uma visão, algumas operações DDL não podem ser executadas diretamente em um cenário específico.
Nota de fundo
GaussDB (DWS) evoluiu do Postgres. Como o Postgres, se uma tabela for referenciada por uma visão, algumas operações DDL não podem ser realizadas diretamente em certos cenários, como modificar o tipo de campo referenciado pela visão, deletar a tabela, etc. Os campos recém-adicionados estão operacionais. O principal motivo é que a visão se refere aos campos da tabela e a visão precisa ser alterada se for modificada. Vamos demonstrar brevemente essa parte do conteúdo a seguir, o que acontecerá quando a tabela referenciada pela visualização realizar operações DDL. Em seguida, veja como modificar os campos da tabela e assim por diante.
Gerar conteúdo experimental
Crie 2 tabelas de teste e 3 visualizações de teste. As instruções SQL construídas são as seguintes. Observe que todas as visualizações usam os campos de t1 e não os campos de t2.
CREATE TABLE t1 (id int,name varchar(20));
CREATE TABLE t2 (id int,name varchar(20));
CREATE OR REPLACE VIEW v1 as select * from t1;
CREATE OR REPLACE VIEW v2 as select a.* from t1 a inner join t2 b on a.id = b.id;
CREATE OR REPLACE VIEW v3 as select a.* from v1 a inner join v2 b on a.id = b.id inner join t1 c on a.id = c.id;
Um, exclua a tabela
DROP TABLE t1;
DROP TABLE t2;
A julgar pelo prompt do resultado da execução, DROP TABLE não foi executado com êxito devido à dependência da visualização. Você pode usar DROP ... CASCADE para deletar visões dependentes juntas, mas em geral, não queremos deletar visões.
Dois, modifique o campo
ALTER TABLE T1 MODIFY NAME VARCHAR(30);
ALTER TABLE T2 MODIFY NAME VARCHAR(30);
A julgar pelos prompts dos resultados da execução, a tabela t1 falhou em modificar o tipo de campo porque a visão v2 usou este campo, e a tabela t2 foi modificada com sucesso porque nenhuma visão usou o campo t2, embora a tabela t2 tenha sido usada na visão, mas apenas Para associação, o campo da visão não usa o campo da tabela t2, portanto o tipo de campo da tabela t2 pode ser modificado com sucesso.
A fim de atingir o objetivo com sucesso nos experimentos subsequentes, modifique a visualização de v2 aqui para obter o campo de t2
ALTER TABLE T2 MODIFY NAME VARCHAR(20);
CREATE OR REPLACE VIEW v2 as select b.* from t1 a inner join t2 b on a.id = b.id;
Três, novos campos
ALTER TABLE t1 ADD COMMENT VARCHAR(30);
ALTER TABLE t2 ADD COMMENT VARCHAR(30);
Não há restrições para adicionar campos, porque quando a visão é criada, não há como referenciar campos que ainda não existem. Revisamos a definição da visualização CREATE VIEW v1 AS SELECT * FROM t1; Haverá alguma nova informação de campo para v1 neste momento? A resposta é não, a visão precisa ser atualizada para ter novos campos
select * from v2;
CREATE OR REPLACE VIEW v2 as select a.* from t1 a inner join t2 b on a.id = b.id;
select * from v2;
Como modificar a definição da tabela referenciada pela visão?
Portanto, a questão é: como podemos modificar a definição da tabela referenciada pela visão semelhante ao campo modificado acima?
Acho que pode ser dividido nas seguintes etapas
Definição da visualização de backup para texto -> definição de tabela de backup para texto -> modificar definição de tabela no texto -> tabela de backup (ALTER TABLE XX RENAME TO XX_BAK) -> adicionar tabela modificada -> inserir dados -> visualização de atualização de texto de visualização de backup
Uma das mais difíceis de obter é: quais visualizações são referenciadas pela tabela? Ele precisa usar o pg_rewrite para obter o relacionamento de referência, e com recursivo .. para obtê-lo ciclicamente.
Um, definição de visualização de backup para texto
Primeiro obtenha a visão do design da tabela, este SQL é um pouco complicado, aqui estão alguns passos para explicar
Obtenha a relação de dependência entre tabelas e visualizações por meio de pg_rewrite
select c.nspname as schemaname,b.relname,rel_oid,b.relkind,d.oid as ori_oid,d.relname ori_name
from (
select unnest(regexp_matches(ev_action::text,':relid (\d+)', 'g'))::oid rel_oid,ev_class --rel_oid 被依赖对象 ,ev_class 视图名称
from pg_rewrite
union
select unnest(regexp_matches(ev_action::text,':resorigtbl (\d+)','g'))::oid,ev_class
from pg_rewrite
) deptbl --pg_write获取依赖关系
inner join pg_class b --被依赖对象获取表名等信息
on deptbl.rel_oid = b.oid
inner join pg_namespace c
on b.relnamespace = c.oid
inner join pg_class d --视图获取视图名等信息,且用于排除pg_write获取的自身对象,即rel_oid <> ev_class
on deptbl.ev_class = d.oid
and deptbl.rel_oid <> d.oid
where b.relname = 't2'; --指定表名t2
Obtenha todas as visualizações relevantes por meio do com xx recursivo como instrução de loop
with recursive rec_view as (
select c.nspname as schemaname,b.relname,rel_oid,b.relkind,d.oid as ori_oid,d.relname ori_name
,0 as level --level防止死循环
from (
select unnest(regexp_matches(ev_action::text,':relid (\d+)', 'g'))::oid rel_oid,ev_class --rel_oid 被依赖对象 ,ev_class 视图名称
from pg_rewrite
union
select unnest(regexp_matches(ev_action::text,':resorigtbl (\d+)','g'))::oid,ev_class
from pg_rewrite
) deptbl --pg_write获取依赖关系
inner join pg_class b --被依赖对象获取表名等信息
on deptbl.rel_oid = b.oid
inner join pg_namespace c
on b.relnamespace = c.oid
inner join pg_class d --视图获取视图名等信息,且用于排除pg_write获取的自身对象,即rel_oid <> ev_class
on deptbl.ev_class = d.oid
and deptbl.rel_oid <> d.oid
where b.relname = 't2' --指定表名t2
union all
select c.nspname,b.relname,deptbl.rel_oid,b.relkind,d.oid as ori_oid,d.relname ori_name,level+1
from (
select unnest(regexp_matches(ev_action::text,':relid (\d+)', 'g'))::oid rel_oid,ev_class
from pg_rewrite
union
select unnest(regexp_matches(ev_action::text,':resorigtbl (\d+)','g'))::oid,ev_class
from pg_rewrite
) deptbl
inner join pg_class b
on deptbl.rel_oid = b.oid
inner join pg_namespace c
on b.relnamespace = c.oid
inner join pg_class d
on deptbl.ev_class = d.oid
and deptbl.rel_oid <> d.oid
inner join rec_view e --循环语句关联条件
on deptbl.rel_oid = e.ori_oid
where level <=10 --level防止死循环
)
select * from rec_view;
A partir do resultado, t2 então as visualizações relacionadas são duas visualizações v2 e v3.
Depois de obter a lista de visualizações, fazemos backup das duas visualizações v2 e v3 para o texto, usando gs_dump.
gs_dump mydb1 -s -t v2 -t v3 -c -f view.ddl -p 25308
2. Fazer backup da definição da tabela para texto -> modificar a definição da tabela no texto -> fazer backup da tabela (ALTER TABLE XX RENAME TO XX_BAK) -> adicionar tabela modificada e inserir dados
Definição da tabela de backup para texto: use gs_dump para exportar a estrutura da tabela de t2 para um arquivo
Modifique a definição da tabela no texto: modifique o tipo de campo do nome do varchar (30) original para varchar (50)
Tabela de backup (ALTER TABLE XX RENAME TO XX_BAK): adicione a ação ALTER TABLE RENAME no texto
Adicione uma tabela modificada e insira dados: adicione SQL para inserir dados no texto
gs_dump mydb1 -s -t t2 -f t2.ddl -p 25308
Depois que o conteúdo acima é modificado, o resultado é o seguinte
Execute a declaração de texto
gsql -d mydb1 -p 25308 -r -f t2.ddl
Três, atualize a vista
Executar visualizações exportadas v2, v3
gsql -d mydb1 -p 25308 -r -f view.ddl
Em seguida, verifique se a definição da tabela t2 foi modificada e se a visualização pode ser consultada
\d t2
select * from v2;
select * from v3;
Resumindo
Como a visualização usa a tabela, haverá uma relação de dependência. Ao modificar a definição da tabela da qual a visualização depende, não há como modificá-la em certas circunstâncias. Aqui eu acho que isso pode ser alcançado pelas seguintes etapas: definição de visualização de backup para texto -> definição de tabela de backup Vá para texto -> modificar a definição da tabela no texto -> tabela de backup (ALTER TABLE XX RENAME TO XX_BAK) -> adicionar tabela modificada -> inserir dados -> visualização de backup visualização de atualização de texto
Para a etapa de definição da visualização de backup, você precisa saber qual é a visualização relacionada da tabela que você precisa modificar. Este processo de consulta precisa usar a tabela pg_rewrite e com xx recursivo para obter recursivamente as visualizações relevantes. Depois que as visualizações relevantes são obtidas e seu backup, as etapas restantes são relativamente simples.
Clique para seguir e aprender sobre a nova tecnologia da Huawei Cloud pela primeira vez ~