FEHLER: Funktion pg_catalog.substring(double precision, integer, integer) existiert nicht

Programmierung mit PostgreSQL (C#, PHP, Perl, Java, ...)
Antworten
ODFvtb
Neuer Benutzer
Beiträge: 5
Registriert: Mo 3. Feb 2020, 12:05

FEHLER: Funktion pg_catalog.substring(double precision, integer, integer) existiert nicht

Beitrag von ODFvtb »

Hallo, ich habe eine PostgrSQL-Datenbank von einen alten Server 2003 auf einen Server 2016 umgezogen.
Backup und Restore der Datenbank habe ich jeweils mit PGAdmin des neuen Server gemacht.(Neue Version 9.5.5..alte Version war 8.1.8)
Die Anwendung (ein QM-System) läuft auch soweit. Nur bei einer wichtigen Funktion bekomme ich folgenden Fehler:
"
FEHLER: Funktion pg_catalog.substring(double precision, integer, integer) existiert nicht LINE 1: SELECT 'R' || SUBSTRING(EXTRACT( YEAR FROM CURRENT_TIMESTAMP... ^ HINT: Keine Funktion stimmt mit dem angegebenen Namen und den Argumenttypen überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen. QUERY: SELECT 'R' || SUBSTRING(EXTRACT( YEAR FROM CURRENT_TIMESTAMP) from 3 for 2) || repeat('0',5-length(rec.anzahl::integer + 1)) || rec.anzahl::integer + 1 CONTEXT: PL/pgSQL-Funktion next_rms() Zeile 6 bei RETURN
INSERT INTO...........FEHLER: aktuelle Transaktion wurde abgebrochen, Befehle werden bis zum Ende der Transaktion ignoriert
SELECT MAX(reklamationsnummer) AS reklamationsnummer FROM rms WHERE ersteller = '44' ""

Kann mir hier jemand weiterhelfen?
Vielen Dank schon mal für Eure Hilfe.

akretschmer
Erfahrener Benutzer
Beiträge: 7715
Registriert: So 29. Okt 2006, 13:35
Wohnort: Kaufbach, Sachsen, Germany, Germany
Kontaktdaten:

Re: FEHLER: Funktion pg_catalog.substring(double precision, integer, integer) existiert nicht

Beitrag von akretschmer »

EXTRACT liefert ein 'double precision', das SUBSTRING erwartet aber da einen String. Vor 8.2 oder 8.3 wurde sowas automatisch gecastet, seit dem ist das nicht mehr der Fall. Ändere das also auf

Code: Alles auswählen

SELECT 'R' || SUBSTRING(EXTRACT( YEAR FROM CURRENT_TIMESTAMP)::text ...
8.1 war übrigens seit November 2010 außer Support, in 9.5 ist die aktuelle Version 9.5.20. Warum tut man sich an, JAHRE hinter den aktuellen Versionen zu sein?
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

castorp
Erfahrener Benutzer
Beiträge: 1202
Registriert: Sa 27. Jun 2009, 22:24
Wohnort: Bayern

Re: FEHLER: Funktion pg_catalog.substring(double precision, integer, integer) existiert nicht

Beitrag von castorp »

Als Erläuterung zu dem was akretschmer geschrieben hat: 9.5 hat ca. noch ein Jahr "zu leben", dann gehört es auch zum alten Eisen.

Details dazu gibt's hier: https://www.postgresql.org/support/versioning/

Wenn man in 2020 ein Migration angeht, sollte man mindestens auf 11, besser auf 12 wechseln.

Ich würde ja extract() in diesem Fall gar nicht verwenden, sondern einfach mittels to_char() formatieren. Auch das Formatieren einer Zahl mit führenden Nullen ist mit to_char() einfacher zu machen:

Der gesamte Ausdruck kann also zu folgendem vereinfacht werden:

Code: Alles auswählen

SELECT 'R' || to_char(CURRENT_TIMESTAMP, 'yy')||to_char(rec.anzahl::integer + 1, 'FM00000')
A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

ODFvtb
Neuer Benutzer
Beiträge: 5
Registriert: Mo 3. Feb 2020, 12:05

Re: FEHLER: Funktion pg_catalog.substring(double precision, integer, integer) existiert nicht

Beitrag von ODFvtb »

Vielen Dank für die schnellen Antworten. Leider weiß ich nicht, wo ich ändern soll. Den Fehler bekomme ich ja, wenn ich eine neue Reklamation in unser QM-System eingebe. Sprich im Browser wird ein php-Script gestartet, welches mir diesen Fehler dann ausspuckt. Muss ich den Code direkt in der Postgresql-Datenbank eingeben? In den php-Dateien finde ich keinen entsprechenden Ausdruck?
Danke!

akretschmer
Erfahrener Benutzer
Beiträge: 7715
Registriert: So 29. Okt 2006, 13:35
Wohnort: Kaufbach, Sachsen, Germany, Germany
Kontaktdaten:

Re: FEHLER: Funktion pg_catalog.substring(double precision, integer, integer) existiert nicht

Beitrag von akretschmer »

Der Browser startet kein PHP-Script, PHP wird auf dem Webserver ausgeführt. Und ja, die Befehle, die die DB ausführt, kommen von der Applikation, hier dann wohl das PHP.

Du solltest Dich mit dem Hersteller der Applikation in Verbindung setzen.
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

ODFvtb
Neuer Benutzer
Beiträge: 5
Registriert: Mo 3. Feb 2020, 12:05

Re: FEHLER: Funktion pg_catalog.substring(double precision, integer, integer) existiert nicht

Beitrag von ODFvtb »

Unser System ist leider schon so alt, dass es den Hersteller nicht mehr gibt. Findet man hier einen Spezialisten, der sich eine Anpassung zutraut? Darf man das Forum überhaupt für die Suche nach einen Spezialisten benutzen?

castorp
Erfahrener Benutzer
Beiträge: 1202
Registriert: Sa 27. Jun 2009, 22:24
Wohnort: Bayern

Re: FEHLER: Funktion pg_catalog.substring(double precision, integer, integer) existiert nicht

Beitrag von castorp »

Grundsätzlich kannst/darfst Du hier fragen. Ich vermute aber mal, dass Du hier nur wenig Erfolg haben wirst, weil PHP Experten unter den Postgres Experten wohl eher dünn gesät sein dürften.

Das richtige Unterforum dazu dürfte wohl: viewforum.php?f=70 sein
A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

ODFvtb
Neuer Benutzer
Beiträge: 5
Registriert: Mo 3. Feb 2020, 12:05

Re: FEHLER: Funktion pg_catalog.substring(double precision, integer, integer) existiert nicht

Beitrag von ODFvtb »

Darf ich nochmal auf mein Problem zurück kommen? Ich habe in eine Backup.sql einen entsprechenen String gefunden. Ich könnte doch versuchen im PSQL-Admin dieses Kommando per Hand einzugeben. Dann mit der "neuen" richtigen Syntax.
In der Backup-Datei habe ich diesen String:
****************************************************************************
CREATE FUNCTION next_rms() RETURNS character varying
AS $$
DECLARE
rec RECORD;
BEGIN
SELECT INTO rec COALESCE(MAX(SUBSTRING(reklamationsnummer from 4 for 5)),'0') AS anzahl FROM reklamationsmanagement."rms" WHERE EXTRACT( YEAR FROM erstelldatum) = EXTRACT(YEAR FROM CURRENT_TIMESTAMP);
RETURN 'R' || SUBSTRING(EXTRACT( YEAR FROM CURRENT_TIMESTAMP) from 3 for 2) || repeat('0',5-length(rec.anzahl::integer + 1)) || rec.anzahl::integer + 1;
END;
$$
LANGUAGE plpgsql;


ALTER FUNCTION reklamationsmanagement.next_rms() OWNER TO ortmaier;
*******************************************************************************************************************
Wie müsste ich diesen denn richtig eingeben? Vielen Dank schon mal.

castorp
Erfahrener Benutzer
Beiträge: 1202
Registriert: Sa 27. Jun 2009, 22:24
Wohnort: Bayern

Re: FEHLER: Funktion pg_catalog.substring(double precision, integer, integer) existiert nicht

Beitrag von castorp »

Ich würde das so umschreiben:

Code: Alles auswählen

CREATE OR REPLACE FUNCTION next_rms() 
  RETURNS character varying
AS $$
DECLARE
  l_anzahl varchar;
BEGIN
  SELECT COALESCE(MAX(SUBSTRING(reklamationsnummer from 4 for 5)),'0')
    INTO l_anzahl
  FROM reklamationsmanagement."rms" 
  WHERE EXTRACT(YEAR FROM erstelldatum) = EXTRACT(YEAR FROM CURRENT_TIMESTAMP);
  
  RETURN 'R' || to_char(CURRENT_TIMESTAMP, 'yy')||to_char(l_anzahl::integer + 1, 'FM00000')
END;
$$
LANGUAGE plpgsql;
Den Befehl dann im SQL client Deiner Wahl (psql, pgAdmin, ...) ausführen.
Vielleicht legst Du die neue Funktion zuerstmal mit dem Namen next_rms_neu() an, und vergleichst das Ergebnis der neuen Funktion mit der alten - nur um sicher zu gehen. Danach kannst Du die alte ja löschen und die neue umbenennen.

Ich weiß Du hast die Funktion nicht geschrieben, aber das System scheint von Leuten programmiert worden zu sein, die sich nicht wirklich gut mit relationalen Datenbank auskennen. Neben der Tatsache, dass man eine Anzahl nicht als Teilstring in einer Spalte "versteckt", gibt es praktisch keine schlechtere Lösung als das "max() + 1" Anti-Pattern um "Nummern" zu generieren (diese Funktion funktioniert vor allem nicht korrekt wenn das von zwei Transaktionen gleichzeitig ausgeführt wird.
A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

ODFvtb
Neuer Benutzer
Beiträge: 5
Registriert: Mo 3. Feb 2020, 12:05

Re: FEHLER: Funktion pg_catalog.substring(double precision, integer, integer) existiert nicht

Beitrag von ODFvtb »

Ändern dieser Funktion hat geholfen.
Bin begeistert. Vielen Dank

Antworten