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 / user-109086

Andy's questions

Martin Hope
Andy
Asked: 2016-11-02 21:41:59 +0800 CST

Queda de colunas do PostgreSQL 9.6 e efeitos colaterais em funções SQL com CTEs

  • 15

Se eu tivesse uma tabela com 3 colunas - digamos A, B e D - e tivesse que introduzir uma nova - digamos C para substituir a posição atual de D. Eu usaria o seguinte método:

  1. Introduzir 2 novas colunas como C e D2.
  2. Copie o conteúdo de D para D2.
  3. Excluir D.
  4. Renomeie D2 para D.

A nova ordem seria A, B, C e D.

Eu pensei que esta era uma prática legítima, pois (até agora) não produziu problemas.

Porém, hoje me deparei com um problema quando uma função realizando um comando na mesma tabela retornou o seguinte erro:

table row type and query-specified row type do not match

E o seguinte detalhe:

Query provides a value for a dropped column at ordinal position 13

Tentei reiniciar o PostgreSQL, fazer um VACUUM FULLe finalmente excluir e recriar a função conforme sugerido aqui e aqui, mas essas soluções não funcionaram (além do fato de tentarem resolver uma situação em que uma tabela do sistema foi alterada).

Tendo o luxo de trabalhar com um banco de dados muito pequeno, exportei-o, excluí-o e importei-o novamente e isso corrigiu o problema com minha função.


Eu estava ciente do fato de que não se deve mexer com a ordem natural das colunas modificando as tabelas do sistema (sujando as mãos com pg_attribute, etc.) como visto aqui:

É possível alterar a ordem natural das colunas no Postgres?

A julgar pelo erro lançado pela minha função, agora percebo que mudar a ordem das colunas com meu método também é um não-não. Alguém pode esclarecer por que o que estou fazendo também está errado?


A versão do Postgres é 9.6.0.

Aqui está a função:

CREATE OR REPLACE FUNCTION "public"."__post_users" ("facebookid" text, "useremail" text, "username" text) RETURNS TABLE (authentication_code text, id integer, key text, stripe_id text) AS '

-- First, select the user:
WITH select_user AS
(SELECT
users.id
FROM
users
WHERE
useremail = users.email),

-- Second, update the user (if user exists):
update_user AS
(UPDATE
users
SET
authentication_code = GEN_RANDOM_UUID(),
authentication_date = current_timestamp,
facebook_id = facebookid
WHERE EXISTS (SELECT * FROM select_user)
AND
useremail = users.email
RETURNING
users.authentication_code,
users.id,
users.key,
users.stripe_id),

-- Third, insert the user (if user does not exist):
insert_user AS
(INSERT INTO
users (authentication_code, authentication_date, email, key, name, facebook_id)
SELECT
GEN_RANDOM_UUID(),
current_timestamp,
useremail,
GEN_RANDOM_UUID(),
COALESCE(username, SUBSTRING(useremail FROM ''([^@]+)'')),
facebookid
WHERE NOT EXISTS (SELECT * FROM select_user)
RETURNING
users.authentication_code,
users.id,
users.key,
users.stripe_id)

-- Finally, select the authentication code, ID, key and Stripe ID:
SELECT
*
FROM
update_user
UNION ALL
SELECT
*
FROM
insert_user' LANGUAGE "sql" COST 100 ROWS 1
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER

Realizei a renomeação/reordenação em ambas as colunas facebook_ide stripe_id(uma nova coluna foi adicionada antes delas, que é o motivo da renomeação, mas não é tocada por esta consulta).

Ter as colunas em uma determinada ordem é puramente interessante para a ordem. No entanto, o motivo de fazer essa pergunta é a preocupação de que uma simples renomeação e exclusão de uma coluna possa desencadear problemas reais para alguém que usa funções no modo de produção (como aconteceu comigo).

postgresql functions
  • 4 respostas
  • 1983 Views
Martin Hope
Andy
Asked: 2016-10-28 00:23:07 +0800 CST

Função PostgreSQL não executada quando chamada de dentro do CTE

  • 17

Apenas esperando para confirmar minha observação e obter uma explicação sobre por que isso está acontecendo.

Eu tenho uma função definida como:

CREATE OR REPLACE FUNCTION "public"."__post_users_id_coin" ("coins" integer, "userid" integer) RETURNS TABLE (id integer) AS '
UPDATE
users
SET
coin = coin + coins
WHERE
userid = users.id
RETURNING
users.id' LANGUAGE "sql" COST 100 ROWS 1000
VOLATILE
RETURNS NULL ON NULL INPUT
SECURITY INVOKER

Quando eu chamo essa função de uma CTE, ela executa o comando SQL mas não aciona a função, por exemplo:

WITH test AS
(SELECT * FROM __post_users_id_coin(10, 1))

SELECT
1 -- Select 1 but update not performed

Por outro lado, se eu chamar a função de um CTE e depois selecionar o resultado do CTE (ou chamar a função diretamente sem CTE) ele executa o comando SQL e aciona a função, por exemplo:

WITH test AS
(SELECT * FROM __post_users_id_coin(10, 1))

SELECT
*
FROM
test -- Select result and update performed

ou

SELECT * FROM __post_users_id_coin(10,1)

Como não me importo muito com o resultado da função (só preciso dela para realizar a atualização), existe alguma maneira de fazer isso funcionar sem selecionar o resultado do CTE?

postgresql cte
  • 2 respostas
  • 2983 Views

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