Chinesische Schriftzeichen müssen true zurückgeben

@castorp @pogomips

Die folgende benutzerdefinierte Funktion akzeptiert keine chinesischen Schriftzeichen. Ich brauche Hilfe.

Ich kenne diesen Funktionscode nicht und weiß nicht, was i c n mx macht
„

select ABCD.FNC_VALIDATE_ALPHA_NUM('武汉市'::text, 0::double PRECISION);

Diese obige Abfrage muss „True“ zurückgeben. Derzeit wird „false“ akzeptiert.



FUNKTION ERSTELLEN ODER ERSETZEN abc.regexp_like(
src_string-Text,
regexp_pat-Text,
p_match_param text DEFAULT 'c'::text)
     Gibt einen booleschen Wert zurück
     SPRACHE 'plpgsql'
     KOSTEN 100
     UNVERÄNDERBAR PARALLEL UNSICHER
ALS $BODY$

ERKLÄREN
     v_match_param TEXT;
     v_like_flag BOOLEAN := FALSE;
START
     – Leerzeichen aus match_param entfernen
     v_match_param := trim(p_match_param);

     – Block zur Überprüfung der Eingabeparameter
     IF (coalesce(src_string, '') = '' OR
         merge(regexp_pat, '') = '')
     DANN
         RETURN v_like_flag;
     ELSIF (coalesce(v_match_param, '') = '') THEN
         v_match_param := 'c';
     ELSIF (v_match_param !~ 'i|c|n|m|x') THEN
         /* Der Wert des Arguments für Parameter an Position „3“ (Match-Parameter)
            muss einer der folgenden sein: „i“, „c“, „n“, „m“, „x“ */
         RAISE USING MESSAGE := 'Ungültiges Argument für Funktion.',
                     DETAIL := 'Der Wert des Arguments muss einer der folgenden sein: „i“, „c“, „n“, „m“, „x“.‘,
                     HINWEIS := '-1760';
     ENDE WENN;

     – Übersetzen Sie Regexp-Flags (Match-Parameter) zwischen passenden Engines
     v_match_param := concat('g', v_match_param);
     v_match_param := regexp_replace(v_match_param, 'm|x', '', 'g');
     v_match_param := CASE
                         WHEN v_match_param !~ 'n' THEN v_match_param || 'P'
                         ELSE regexp_replace(v_match_param, 'n', '', 'g')
                      ENDE;

     – Finden, ob es eine Übereinstimmung mit der bereitgestellten Regexp-Maske gibt
     v_like_flag := EXISTS(SELECT regexp_matches(src_string, regexp_pat, v_match_param));

     RETURN v_like_flag;
ENDE;
$KÖRPER$;

KOMMENTAR ZUR FUNKTION abc.regexp_like(text, text, text)
     IS 'Diese Funktion gibt einen booleschen Wert zurück, der angibt, ob das reguläre Ausdrucksmuster in einer Zeichenfolge gefunden wird.';
„



FUNKTION ERSTELLEN ODER ERSETZEN abcd.fnc_validate_alpha_num(
f_data-Text,
f_datatype_constant (doppelte Genauigkeit)
     Gibt einen booleschen Wert zurück
     SPRACHE 'plpgsql'
     KOSTEN 100
     FLÜCHTIG PARALLEL UNSICHER
ALS $BODY$

ERKLÄREN
     vfc DOPPELTE PRÄZISION;
     is_valid BOOLEAN;
START
  
     is_valid := FALSE;
     vfc := 0;

     WENN f_datatype_constant = 0 DANN
         WÄHLEN
             ZÄHLEN(*)
             IN STRENGE VFC
             WHERE abc.regexp_like((f_data)::TEXT, ('^[ !-’~¡-ÿ]*$')::TEXT);

         WENN vfc = 0 DANN
             is_valid := FALSE;
         ANDERS
             is_valid := TRUE;
         ENDE WENN;
     /* END IF; */
     ELSIF f_datatype_constant = 1 DANN
         WÄHLEN
             ZÄHLEN(*)
             IN STRENGE VFC
             WHERE abc.regexp_like((f_data)::TEXT, ('^[0-9]*$')::TEXT);

         WENN vfc = 0 DANN
             is_valid := FALSE;
         ANDERS
             is_valid := TRUE;
         ENDE WENN;
     /* END IF; */
     ELSIF f_datatype_constant = 2 DANN
         WÄHLEN
             ZÄHLEN(*)
             IN STRENGE VFC
             WHERE abc.regexp_like((f_data)::TEXT, ('^[a-zA-Z]*$')::TEXT);

         WENN vfc = 0 DANN
             is_valid := FALSE;
         ANDERS
             is_valid := TRUE;
         ENDE WENN;
   
     ELSIF f_datatype_constant = 3 DANN
         WÄHLEN
             ZÄHLEN(*)
             IN STRENGE VFC
             WHERE abc.regexp_like((f_data)::TEXT, ('^[a-zA-Z0-9]*$')::TEXT);

         WENN vfc = 0 DANN
             is_valid := FALSE;
         ANDERS
             is_valid := TRUE;
         ENDE WENN;

     ENDE WENN;
     RETURN (is_valid);
ENDE;
$KÖRPER$;

Du hast wieder alles auf Deutsch übersetzt. Könntest Du so freundlich sein, den Code nicht zu übersetzen?

Wenn Du auf alpha_numerische Werte prüfen willst, wäre es vielleicht einfacher, auf “nicht numerisch” zu prüfen". Das könntest Du mit einer überwachten Typkonvertierung machen wie hier:
Solange der Code Deutsch ist, schon mal ein Vorschlag ins Blaue:

CREATE OR REPLACE FUNCTION isnumeric(text) RETURNS BOOLEAN AS $
DECLARE x NUMERIC;
BEGIN
    x = $1::NUMERIC;
    RETURN TRUE;
EXCEPTION WHEN others THEN
    RETURN FALSE;
END;
$
STRICT
LANGUAGE plpgsql IMMUTABLE;

Dieser Ansatz ist u.U. nur sinnvoll, wenn die Mehrheit der Prüfwerte tatsächlich Zahlen sind. Da sonst zu viele Exceptions eintreten und es langsam machen.

1 „Gefällt mir“

select INV_NO,abc.REGEXP_LIKE(TRIM(coalesce(INV_NO_ ‘0’)), ‘^[0]{1,}$’)
,abc.REGEXP_LIKE(coalesce(INV_NO,‘0’), ‘^\s+$’)
from abc_wbm.wbminv where inv_no= ‘3268145’

This must return false but its returning true after i changed

from v_like_flag := EXISTS(SELECT regexp_matches(src_string, regexp_pat,

to v_like_flag := EXISTS(SELECT regexp_match(src_string, regexp_pat,

Chinese characters accepting but its failing in the above scenario.
select abcd.FNC_VALIDATE_ALPHA_NUM(‘武汉市’::text, 0::double PRECISION);


CREATE OR REPLACE FUNCTION abc.regexp_like(
	src_string text,
	regexp_pat text,
	p_match_param text DEFAULT 'c'::text)
    RETURNS boolean
    LANGUAGE 'plpgsql'
    COST 100
    IMMUTABLE PARALLEL UNSAFE
AS $BODY$

DECLARE
    v_match_param TEXT;
    v_like_flag BOOLEAN := FALSE;
BEGIN
    -- Removing spaces from match_param
    v_match_param := trim(p_match_param);

    -- Block of input parameters validation checks
    IF (coalesce(src_string, '') = '' OR
        coalesce(regexp_pat, '') = '')
    THEN
        RETURN v_like_flag;
    ELSIF (coalesce(v_match_param, '') = '') THEN
        v_match_param := 'c';
    ELSIF (v_match_param !~ 'i|c|n|m|x') THEN
        /* The value of the argument for parameter in position "3" (match parameter)
           must be one of the following: "i", "c", "n", "m", "x" */
        RAISE USING MESSAGE := 'Illegal argument for function.',
                    DETAIL := 'The value of the argument must be one of the following: "i", "c", "n", "m", "x".',
                    HINT := '-1760';
    END IF;

    -- Translate regexp flags (match parameter) between matching engines
    v_match_param := concat('g', v_match_param);
    v_match_param := regexp_replace(v_match_param, 'm|x', '', 'g');
    v_match_param := CASE
                        WHEN v_match_param !~ 'n' THEN v_match_param || 'p'
                        ELSE regexp_replace(v_match_param, 'n', '', 'g')
                     END;

    -- Finding if there is a match regarding supplied regexp mask
    v_like_flag := EXISTS(SELECT regexp_matches(src_string, regexp_pat, v_match_param));

    RETURN v_like_flag;
END;
$BODY$;

COMMENT ON FUNCTION abc.regexp_like(text, text, text)
    IS 'This function returns a boolean value indicating if the regular expression pattern is found in a string.';

@pogomips @castorp Any help?

Was machst Du da?!
Änderst Du Postgres Funktionen?
Du willst ganz bestimmt nicht postgres Funktionen ändern!

Und wieso fragst Du das hier? Wenn Du eine Funktion gegene eine andere Funktion tauscht, die Dir besser gefällt, schau einfach in die Dokumentation, was der Unterschied ist.

Allein, dass Du als Stichprobe in diesem Fall das gewünschte Ergebnis erhälst (bei einer 1:1 Chance bzw true versus false), kann kein Grund dafür sein.

Das EXISTS macht dort keinen Sinn.

regexp_match liefert immer einen Wert (auch wenn der NULL sein kann). EXISTS prüft nur ob was zurückgeliefert wurde, der eigentlich Wert is irrelevant. Der Ausdruck ist also letztendlich das Gleiche wie v_like_flag := exists (select null); wenn kein Match existiert oder v_like_flag := exists (select 1); wenn ein Match existiert - beides ist identisch zu v_like_flag := true;

Wenn Du prüfen wills ob das Pattern passt, dann verwende

v_like_flag := regexp_match(...) is not null; 

oder einfach

v_like_flag := src_string ~ regexp_pat;

Seit Postgres 15 gibt es übrigens auch ein regexp_like was letztendlich dem ~ operator entspricht (und soweit ich weiß kompatibel mit der Oracle Implementierung ist)

1 „Gefällt mir“

Die folgenden Zeichenfolgen werden nicht akzeptiert. Dies muss true zurückgeben.

Ich denke, dass winzige Änderungen erfordern, dass das Regexp-Muster diese Zeichenfolgen akzeptiert.

FACTORY BUILDING 2 LANE 31 YIWEI ROAD CHINA(SH → False

HUABO BIOPHARM(SHANGHAI) CO. LTD → ,False

EVIVE(BEIJING) BIOTECH CO. LTD. ->,False

OBIO TECHNOLOGY(SHANGHAI)CORP. LTD ->,False

天津西青区华苑产业区(环外)海泰发展五道16号B-2-3-702 ->,False

QILU PHARMACEUTICAL(HAINAN) CO. LTD.,False




CREATE OR REPLACE FUNCTION abcd.fvan(
   q_data text,
   q_datatype_constant double precision)
   RETURNS boolean
   LANGUAGE 'plpgsql'
   COST 100
   VOLATILE PARALLEL UNSAFE
 AS $BODY$
 DECLARE
   vfc DOUBLE PRECISION;
   is_valid BOOLEAN;
 BEGIN

   is_valid := FALSE;
   vfc := 0;
 
   IF q_datatype_constant = 0 THEN
       SELECT
           COUNT(*)
           INTO STRICT vfc
          WHERE abc.regexp_like((q_data)::TEXT,
                                  ('^[ !-’~,\s\ & 。. . ,、 ()#/¡-ÿ]*$')::TEXT)
            OR abc.regexp_like((q_data)::TEXT,('^[^[:ascii:]]+$')::TEXT);
 
       IF vfc = 0 THEN
           is_valid := FALSE;
       ELSE
           is_valid := TRUE;
       END IF;
   /* END IF; */
   ELSIF q_datatype_constant = 1 THEN
       SELECT
           COUNT(*)
           INTO STRICT vfc
           WHERE abc.regexp_like((q_data)::TEXT, ('^[0-9。, 、 ()#\-\s\ & . . ,/]*$')::TEXT);
 
       IF vfc = 0 THEN
           is_valid := FALSE;
       ELSE
           is_valid := TRUE;
       END IF;
   /* END IF; */
   ELSIF q_datatype_constant = 2 THEN
       SELECT
           COUNT(*)
           INTO STRICT vfc
           WHERE abc.regexp_like((q_data)::TEXT, ('^[a-zA-Z(\-\s\ , 、 & .。. , ()#/]*$')::TEXT);
 
       IF vfc = 0 THEN
           is_valid := FALSE;
       ELSE
           is_valid := TRUE;
       END IF;
   /* --ALM#10626 changes starts */
   ELSIF q_datatype_constant = 3 THEN
       SELECT
           COUNT(*)
           INTO STRICT vfc
           WHERE abc.regexp_like((q_data)::TEXT, ('^[a-zA-Z(0-9\-\s\ , 、 & . 。 ()#/]*$')::TEXT);
 
       IF vfc = 0 THEN
           is_valid := FALSE;
       ELSE
           is_valid := TRUE;
       END IF;
   /* --ALM#10626 changes ends */
   END IF;
   RETURN (is_valid);
 END;
 $BODY$;

@castorp

Dieses Thema wurde automatisch 60 Tage nach der letzten Antwort geschlossen. Es sind keine neuen Antworten mehr erlaubt.