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 / 297529
Accepted
Adam Mulla
Adam Mulla
Asked: 2021-08-04 06:23:09 +0800 CST2021-08-04 06:23:09 +0800 CST 2021-08-04 06:23:09 +0800 CST

Como usar a exceção definida pelo usuário - Função PostgreSQL

  • 772

Você pode fornecer a sintaxe para usar a exceção definida pelo usuário na função PostgreSQL?

Suponha que eu queira lidar com a exceção definida pelo usuário.

SQL Error [22023]: ERROR: password is too short.

Existem vários códigos de erro SQLSTATE, mas não é possível encontrar qual é o código SQLSTATE para este erro. Usei acima que é 22023 mas não resolveu.

Temos abaixo o código que podemos gerenciar a exceção relacionada à violação exclusiva, mas não podemos gerenciar "a senha é muito curta". poderia me ajudar com a sintaxe?

Código:

begin
EXECUTE 'ALTER USER ' || $1 || ' WITH PASSWORD '''|| $2||'''' ;
        EXCEPTION WHEN "Password is too short" 
        THEN RAISE DETAIL 'Please check your password';
        
INSERT INTO pwdhistory (usename,password,changed_on) values($1,md5($2),now());
        EXCEPTION WHEN unique_violation 
        THEN RAISE DETAIL 'Password already used earlier. Please try again with another password.';

end;
postgresql plpgsql
  • 1 1 respostas
  • 1053 Views

1 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2021-08-04T15:52:53+08:002021-08-04T15:52:53+08:00

    Capturando e levantando erros

    Para interceptar erros , use apenas uma EXCEPTION cláusula no código PL/pgSQL. Pode ter várias WHENcláusulas. (Mas você parece precisar apenas de um . Veja abaixo.)

    Você pode trabalhar com códigos de erro como com nomes de condição. A lista de códigos de erro pode ser encontrada no manual .

    Considere também a página de manual do Postgres sobre interceptação de erros em PL/pgSQL :

    Os nomes das condições podem ser qualquer um dos mostrados no Apêndice A. Um nome de categoria corresponde a qualquer erro em sua categoria. [...] Além disso, uma condição de erro pode ser especificada por SQLSTATEcódigo; por exemplo, estes são equivalentes:

    WHEN division_by_zero THEN ...
    WHEN SQLSTATE '22012' THEN ...
    

    Assim, você pode capturar erros e (re-)aumentá-los com detalhes diferentes ou adicionais.

    Levantar seus próprios erros é uma questão diferente.
    Basta usar RAISEcom todos os detalhes desejados. Não é necessário interceptar um erro primeiro.

    injeção SQL

    Não relacionado à sua pergunta principal, seu código exibido está aberto à injeção de SQL.

    EXECUTE 'ALTER USER ' || $1 || ' WITH PASSWORD '''|| $2||'''' ;
    

    Não use isso.

    Seria divertido chamar sua função com:

    SELECT my_func('user1', 'pw1234567''; DELETE FROM pwdhistory; --');
    

    (Ou pior.) Boom. Ver:

    • https://xkcd.com/327/

    Manipule a entrada do usuário corretamente. Ver:

    • Injeção de SQL em funções do Postgres vs consultas preparadas

    Função

    Sua função pode ficar assim (assumindo o Postgres 13 atual):

    CREATE OR REPLACE FUNCTION myfunc(_usename text, _password text)
      RETURNS void
      LANGUAGE plpgsql AS
    $func$
    DECLARE
       _min_password_length int := 8;  -- specify min length here
    BEGIN
       IF length(_password) >= _min_password_length THEN
          EXECUTE format('ALTER USER %I WITH PASSWORD %L', _usename, _password);
       ELSE  -- also catches NULL
          -- raise custom error
          RAISE EXCEPTION 'Password too short!'
          USING ERRCODE = '22023'  -- 22023 = "invalid_parameter_value'
              , DETAIL = 'Please check your password.'
              , HINT = 'Password must be at least ' || _min_password_length || ' characters.';
       END IF;
    
       
       INSERT INTO pwdhistory
              (usename, password, changed_on)
       VALUES ($1     , md5($2) , now());
    
    EXCEPTION
       -- trap existing error and re-raise with added detail
       WHEN unique_violation THEN  -- = error code 23505   
          RAISE unique_violation
          USING DETAIL = 'Password already used earlier. Please try again with a different password.';
    END
    $func$;
    

    db<>fique aqui

    Observe o uso de format()para citar corretamente o nome e o valor e defenda-se contra injeção de SQL.

    Ligar:

    SELECT myfunc('usr', 'pw'); -- PW obviously too short ...
    

    Produz:

    ERROR:  Password too short!
    DETAIL:  Please check your password.
    HINT:  Password must be at least 8 characters.
    CONTEXT:  PL/pgSQL function pg_temp_5.foo(text,text) line 8 at RAISE
    SQL state: 22023
    
    SELECT myfunc('usr', 'repeated_pw');
    

    Produz:

    ERROR:  unique_violation
    DETAIL:  Password already used earlier. Please try again with a different password.
    CONTEXT:  PL/pgSQL function pg_temp_5.foo(text,text) line 21 at RAISE
    SQL state: 23505
    
    • 2

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