42883 ошибка postgresql

As the documentation says:

The trigger function must be defined before the trigger itself can be
created. The trigger function must be declared as a function taking
no arguments and returning type trigger
. (The trigger function
receives its input through a specially-passed TriggerData structure,
not in the form of ordinary function arguments.)

The function you have declared is:

insertIntoAutoIncrementExample(companyname text,location text) ... returns void

so it does not fit both in the return type and in the argument types.
A trigger function does not take arguments but can access the values inserted or changed in the row variables NEW and OLD. They get automatically defined in plpgsql, see Trigger procedures in the plpgsql chapter for details and examples.

Concerning the error message:

function insertintoautoincrementexample() does not exist

it means: this function name, with an empty list of arguments, does not exist.
The presence of parentheses around nothing is relevant, because in postgresql, functions always go with their argument types:
foobar(int) is not the same function than foobar(), or foobar(int,int) or foobar(text).

I searched for this without much luck… I hope you can help me…

This is my PL/pgSQL function:

CREATE OR REPLACE FUNCTION crearempresa(
    _id_empresa integer DEFAULT NULL::integer,
    _ci_rif character varying DEFAULT NULL::character varying,
    _nombre character varying DEFAULT NULL::character varying,
    _persona_contacto character varying DEFAULT NULL::character varying,
    _telefono_movil character varying DEFAULT NULL::character varying,
    _telefono_oficina character varying DEFAULT NULL::character varying,
    _fax character varying DEFAULT NULL::character varying,
    _email character varying DEFAULT NULL::character varying,
    _email_alterno character varying DEFAULT NULL::character varying,
    _direccion character varying DEFAULT NULL::character varying,
    _tipoempresa character varying DEFAULT NULL::character varying,
    _cod_usuario integer DEFAULT NULL::integer,
    _estado_registro integer DEFAULT NULL::integer
)
  RETURNS character varying AS
$BODY$
    DECLARE
        retorno character varying;
    BEGIN
        IF _id_empresa = 0 THEN
            _id_empresa = NULL;
        END IF;
        IF (select id_empresa from empresa where id_empresa = _id_empresa) is null THEN
            IF (Select MAX(id_empresa) from empresa) is null THEN
                _id_empresa = 1;
            ELSE
                _id_empresa = (Select MAX(id_empresa) + 1 from empresa);
            END IF;
            insert into empresa (
                id_empresa,ci_rif,nombre,persona_contacto,telefono_movil,telefono_oficina,fax,email,
                email_alterno,direccion,id_tipo_empresa,cod_usuario,fecha_creacion,fecha_actualizacion,estado_registro)
            values (
                _id_empresa,_ci_rif,_nombre,_persona_contacto,_telefono_movil,_telefono_oficina,_fax,_email,            
                _email_alterno,_direccion,_tipoempresa,_cod_usuario,CURRENT_DATE,CURRENT_DATE,_estado_registro);
            retorno = '1';      
        ELSE
            Update empresa
               set ci_rif = _ci_rif,            
                   nombre = _nombre,            
                   persona_contacto = _persona_contacto,            
                   telefono_movil = _telefono_movil,        
                   telefono_oficina = _telefono_oficina,            
                   fax = _fax,          
                   email = _email,          
                   email_alterno = _email_alterno,          
                   direccion = _direccion,      
                   id_tipo_empresa = _tipoempresa,  
                   cod_usuario = _cod_usuario,          
                   fecha_actualizacion = CURRENT_DATE,          
                   estado_registro = _estado_registro
             where id_empresa = _id_empresa;
            retorno = '2';
        END IF;                   
        RETURN retorno;
    END;
 $BODY$
 LANGUAGE plpgsql VOLATILE COST 100;

It was created fine, because I can see the function inside the folder ‘Functions’ in pgAdminIII:

enter image description here

I when I try to test the function using:

select crearempresa (1,'a','f','a','b','c','d','e','f','g',4,1,1);

I get the following error message:

ERROR:  no existe la función crearempresa(integer, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, integer, integer, integer)
LINE 1: select crearempresa (1,'a','f','a','b','c','d','e','f','g',4...
               ^
HINT:  Ninguna función coincide en el nombre y tipos de argumentos. Puede ser necesario agregar conversión explícita de tipos.
********** Error **********

ERROR: no existe la función crearempresa(integer, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, integer, integer, integer)
SQL state: 42883
Hint: Ninguna función coincide en el nombre y tipos de argumentos. Puede ser necesario agregar conversión explícita de tipos.
Character: 8

I just don’t know which one is the correct aproach to solve this issue. It looks like somehow PostgreSQL can’t locate the function even though it’s already created, as you can see in the picture. Or maybe, it has something to do with datatypes, but I just can’t understand why, because in the function definition the datatypes are equal to the parameters in the function call. Besides, I already have many functions similar to this and all worked fine…

Hope you can help me understand this…

Thanks in advance!

I’ve done some more digging. The issue isn’t with the parameter type, but with the fact that a name is specified. In PostgreSQL you can call a function with positional (SELECT * FROM foo(8) or named (SELECT * FROM foo(bar => 8)) argument style. Unfortunately it seems that like many other internal functions, pg_try_advisory_lock does not actually have parameter names, so you can only call it positionally. To do this, do not set the NpgsqlParameter’s name («key») — just leave it empty. This will make PostgreSQL generate the positional style, which should work.

For reference, the following reproduces your issue:

using var cmd = new NpgsqlCommand("pg_try_advisory_lock", conn);
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("key", NpgsqlDbType.Bigint, 8); // Note "key" parameter name
    cmd.ExecuteNonQuery();
}

While the following works:

using var cmd = new NpgsqlCommand("pg_try_advisory_lock", conn);
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue(NpgsqlDbType.Bigint, 8); // Note no parameter name
    cmd.ExecuteNonQuery();
}

The query that shows method along with their parameter names and types:

SELECT
    proname,
    CASE
        WHEN pg_proc.proargnames IS NULL THEN array_cat(array_fill(''::name,ARRAY[pg_proc.pronargs]),array_agg(pg_attribute.attname ORDER BY pg_attribute.attnum))
        ELSE pg_proc.proargnames
        END AS proargnames,
    pg_proc.proargtypes,
    CASE
        WHEN pg_proc.proallargtypes IS NULL AND (array_agg(pg_attribute.atttypid))[1] IS NOT NULL THEN array_cat(string_to_array(pg_proc.proargtypes::text,' ')::oid[],array_agg(pg_attribute.atttypid ORDER BY pg_attribute.attnum))
        ELSE pg_proc.proallargtypes
        END AS proallargtypes,
    CASE
        WHEN pg_proc.proargmodes IS NULL AND (array_agg(pg_attribute.atttypid))[1] IS NOT NULL THEN array_cat(array_fill('i'::"char",ARRAY[pg_proc.pronargs]),array_fill('o'::"char",ARRAY[array_length(array_agg(pg_attribute.atttypid), 1)]))
        ELSE pg_proc.proargmodes
        END AS proargmodes
FROM pg_proc
         LEFT JOIN pg_type ON pg_proc.prorettype = pg_type.oid
         LEFT JOIN pg_attribute ON pg_type.typrelid = pg_attribute.attrelid AND pg_attribute.attnum >= 1 AND NOT pg_attribute.attisdropped
GROUP BY proname, pg_proc.proargnames, pg_proc.proargtypes, pg_proc.proallargtypes, pg_proc.proargmodes, pg_proc.pronargs;

For proname=’pg_try_advisory_lock’, the proargnames column doesn’t contain names like for other functions.

SOLVE ALL THE ERRORS!

This post was most recently updated on March 16th, 2023.

3 min read.

Have you run into this puzzling error? It comes in a couple of flavors, but it boils down to you failing miserably when you run the create_hypertable() function on your PostgreSQL TimescaleDB database server! Annoyingly, it might mean that the whole function is missing (extension is not installed or loaded) or that your parameters are not properly parsed (an issue with your command).

I know, that it sucks. I have been there. That’s why I wrote this article!

Problem

Table of Contents

You’re trying to transform your PostgreSQL database/schema, possibly already using TimescaleDB, into a Hypertable. However, that fails and throws an error like this:

Npgsql: 42883: function create_hypertable(…) does not exist.

You might get the parameters populated like this:

Npgsql: 42883: function create_hypertable('TableOne','created') does not exist.

Or they might be unknown like this:

Npgsql: 42883: function create_hypertable(unknown, unknown) does not exist.

Reason

You’ll either be missing the extension from the server, it might not be loaded properly, it might be missing from your database, or your command might be using bad or corrupted parameters.

Below, I’ll go through the solutions to these issues!

Solution

The simple tutorial below explains step-by-step what to do (or verify) to get this working!

Time needed: 20 minutes

How to configure your PostgreSQL/TimescaleDB to support Hypertables?

  1. Add Hypertables extension to your database server

    Navigate to your PostgreSQL server, select “Server parameters” and then find “shared_preload_libraries” – it should be a dropdown, from which you can enable TIMESCALEDB.

    Then navigate back to Overview of your PostgreSQL server and select Restart.

  2. Add Hypertables extension to your database (schema)

    Connect to your PostgreSQL database with psql (or any other such tool), and run the following SQL:
    \c "YourSchema"
    CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;

    I guess technically speaking you could also insert this into an EF Core Migration!

    In case you’re wondering how to connect to your Azure PostgreSQL Server with psql, you can do this with Cloud Shell – and it’s really easy! See here:
    How to configure Azure PostgreSQL to allow Cloud Shell connections?

  3. (OPTIONAL) Add an empty EF Core Migration

    Do this only if you’re using Entity Framework in the first place. 😅 Just run Add-Migration

  4. Change a table into a hypertable with a function

    create_hypertable() is a function that has a couple of alternative signatures – the one I’ll be using takes the (1) table name first and (2) the column name of the column containing time values (as well as the primary column to partition by).

    You will need to call this function, and instead of actually transforming or changing a table into a hypertable, it creates a new hypertable based on your old table – and deletes the old one. This is irreversible!

    Additionally, it is a SELECT <function_name> -kinda command. We can live with that – it’ll look somewhat like the below:
    SELECT create_hypertable(‘”TableOne”‘, ‘Created’)

    Wait, WAIT – what’s with the weird quotes?

    Yep, that’s what it takes – the column name needs to be in single quotes, but the table name needs to be first in double quotes (if not in lowercase), then wrapped in single quotes.

  5. (OPTIONAL) Run create_hypertable in your EF Core Migration

    There are a couple of exact ways that you can write this command, but at the end of the day, you’ll probably be using migrationBuilder.Sql to run your SQL commands (in case you’re using EF, that is).

    At the end of the day, your migration and command(s) might look somewhat like this:
    protected override void Up(MigrationBuilder migrationBuilder)
    {
    migrationBuilder.Sql(@"SELECT create_hypertable('""TableOne""', 'Created')");
    migrationBuilder.Sql(@"SELECT create_hypertable('""TableTwo""', 'Created')");
    }

    Wait, wait, WAIT! This is even weirder now, with different quotes and literal string??

    Yeah, it is pretty weird, sure.

    The column name needs to be in single quotes, but the table name needs to be first in double-quotes (if not in lowercase), then in single quotes, and finally the double-quotes need to be escaped (for string literal).

    I couldn’t get the normal escape (non-literal string with \”) to work, so this was my workaround (using @ to make the string literal)… 😉


And that’s it! Let me know if it works for you as well in the comments -section below! ☺

References

  • https://docs.timescale.com/timescaledb/latest/how-to-guides/hypertables/
  • Power IoT and time-series workloads with TimescaleDB for Azure Database for PostgreSQL
  • https://techinplanet.com/how-do-i-create-a-hypertable-with-timescaledb-from-a-table-with-joint-primary-key/
  • https://github.com/timescale/timescaledb/issues/747
  • Author
  • Recent Posts

mm

Antti Koskela is a proud digital native nomadic millennial full stack developer (is that enough funny buzzwords? That’s definitely enough funny buzzwords!), who works as Solutions Architect for Precio Fishbone, building delightful Digital Workplaces.

He’s been a developer from 2004 (starting with PHP and Java), and he’s been working on .NET projects, Azure, Office 365, SharePoint and a lot of other stuff. He’s also Microsoft MVP for Azure.

This is his personal professional (e.g. professional, but definitely personal) blog.

mm

I want to insert a new row to Table2 when Table 1 is inserted a row. I have created a function for that. However, when I try to create the trigger, it gives an error although function is created and I can see the function.

SQL Error [42883]: ERROR: function insertintoautoincrementexample() does not exist

Following are the details related to it. I tried to create the trigger with some text parameters but no luck.

//Table 1
CREATE TABLE myOriginalTable(
    companyName VARCHAR(15) PRIMARY KEY NOT NULL,
    location VARCHAR(30)    
);    

//Table 2    
CREATE TABLE autoincrementexample (
    entryid INT4 NOT NULL DEFAULT nextval('autoincrementexample_entryid_seq'::regclass),
    companyname VARCHAR(15) NOT NULL,
    location VARCHAR(30) NOT NULL,
    PRIMARY KEY (companyname)
);

//Function    
CREATE OR REPLACE FUNCTION insertIntoAutoIncrementExample(companyname text,location text)

    returns void
    language plpgsql
    as $function$

    declare
    varaudseq bigint;

    begin
        varaudseq :=0;

    begin
        SELECT NEXTVAL(autoincrementexample) INTO varaudseq;
        INSERT INTO autoincrementexample(companyname,location)VALUES(companyName,location);
    COMMIT;
    END;
    END;
    $function$;

//Trigger
CREATE TRIGGER after_insert_original 
    AFTER INSERT ON myoriginaltable
    FOR EACH row
    EXECUTE PROCEDURE insertintoautoincrementexample();

Would appreciate any help regarding this.

Понравилась статья? Поделить с друзьями:

Интересное по теме:

  • 4270 ошибка фольксваген
  • 426e ошибка бмв
  • 426 ошибка http
  • 4252 bmw ошибка
  • 42501 ошибка нет доступа к последовательности

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии