AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 141113
Accepted
tomka
tomka
Asked: 2016-06-14 07:56:59 +0800 CST2016-06-14 07:56:59 +0800 CST 2016-06-14 07:56:59 +0800 CST

Citação de regclass PL/pgSQL da tabela nomeada como palavra-chave

  • 772

Desejo criar um novo nome de tabela com base em um existente anexando um sufixo a ele. Uma função PL/pgSQL do Postgres 9.5 obtém o nome da tabela existente passado como regclasstipo e retorna o novo nome como uma string. Estou usando format()para construir o novo nome e normalmente usaria o %Iespaço reservado. Isso funciona desde que o nome da tabela passado não corresponda a nenhuma palavra-chave PL/pgSQL. Nesse caso, independentemente do tipo de componente que eu escolher ( %Iou %s), a citação está errada.

Considere a seguinte função:

CREATE OR REPLACE FUNCTION make_name(old_name regclass)
RETURNS text                                           
LANGUAGE plpgsql AS                                    
$$                                                     
BEGIN                                                  
    RETURN format('%I_new', old_name);                 
END;                                                   
$$;                                                    

Além disso, suponha que haja duas tabelas: treenodee overlay. Chamar esta função para ambos resulta nos seguintes novos nomes:

SELECT make_name('overlay'::regclass);
     make_name     
-------------------
 """overlay"""_new
(1 row)

SELECT make_name('treenode'::regclass);
  make_name   
--------------
 treenode_new
(1 row)

Acontece que overlaytambém é uma função PL/pgSQL (assim como format, mas treenodenão é), que parece alterar o comportamento de citação. Se %sfor usado com format(), o resultado seria "overlay"_new. O mesmo acontece quando utilizo a ||operadora. Se eu usar textcomo tipo de parâmetro de entrada, tudo funcionará conforme o esperado, mas prefiro usar regclass.

Existe uma maneira de formatar uma string com um regclassnome de tabela de correspondência de palavra-chave (por exemplo overlay) sem aspas, assim como é o caso de um regclassnome de tabela de correspondência de palavra-chave (por exemplo treenode)?

postgresql datatypes
  • 2 2 respostas
  • 2479 Views

2 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2016-06-20T18:50:53+08:002016-06-20T18:50:53+08:00

    Explicação

    Vou percorrer as várias camadas de mal-entendidos, uma a uma - chegando a uma solução simples e segura.

    0.

    A razão pela qual overlayestá entre aspas não é porque é um nome de função, mas porque é uma palavra reservada .
    Além disso, nãooverlay() é uma "função PL/pgSQL" (nem palavra-chave PL/pgSQL), é uma função SQL padrão incorporada ao núcleo do Postgres ( , então C por trás das cortinas). Na verdade, PL/pgSQL não tem nada a ver com nada disso.LANGUAGE internal

    1.

    Um simples erro de lógica.

    format('%I_new', old_name)

    Isso escaparia de qualquer identificador não padrão com aspas antes de '_new' ser anexado e falharia mesmo com texto tipo de entrada. Você deve acrescentar '_new' antes de citar tudo:

    format('%I', old_name || '_new')
    

    Mas isso ainda não funcionará para regclass. Continue lendo.

    2.

    Não faz sentido adicionar aspas a uma regclassvariável com %I, pois sua representação de texto já é citada automaticamente quando necessário. (Semelhante a quote_ident(), mas não pode ser NULL; já que a entrada regclassnão pode ser NULL para começar.) Você o aplicaria duas vezes . Sempre use %spara regclassentrada (a string como está).

    3.

    format()é um exagero para isso. Basta usar quote_ident():

    quote_ident(old_name || '_new')
    
    4.

    Mais importante , como mencionado acima, atextrepresentação de umaregclassvariável é automaticamente escapada. Isso está embutido no elenco. Para obter o texto bruto, recupere-diretamente do catálogo do sistema . pg_classUmregclass valor é apenas ooiddesta tabela internamente.

    SELECT relname FROM pg_class WHERE oid = $1;
    

    Solução

    Isso faz o que você está procurando:

    CREATE OR REPLACE FUNCTION make_name(old_name regclass)
      RETURNS text AS
    $func$
    SELECT quote_ident(relname || '_new') FROM pg_class WHERE oid = $1;
    $func$  LANGUAGE sql STABLE;
    

    Teste

    CREATE TEMP TABLE "sUICiDAL' namE"();
    CREATE TEMP TABLE overlay();
    
    SELECT make_name('overlay') AS n1
         , make_name('"sUICiDAL'' namE"')  AS n2;
    
         n1      |          n2
    -------------+----------------------
     overlay_new | "sUICiDAL' namE_new"
    

    Observe que overlay_newé um identificador perfeitamente legal, portanto não é citado.

    Se você quiser o nome sem escape (sem aspas), basta usar:

    SELECT relname || '_new' FROM pg_class WHERE oid = $1;
    
    • 8
  2. smbennett1974
    2016-06-18T02:10:52+08:002016-06-18T02:10:52+08:00

    A única maneira que consegui pensar foi agrupar a chamada para a formatfunção da translateseguinte maneira:

    RETURN translate(format('%I_new',old_name),'"','');
    

    Esta postagem processa a saída do formato e remove os "caracteres.

    Não sei se alguém tem uma solução mais elegante. Pensei em btrim, rtrim etc... mas precisaria de uma chamada para cada um.

    • 1

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve