Я пытаюсь построить функцию, где я смог бы сделать что-то вроде этого:Создать функцию, заменяющую varchar таблицей словаря?
replace_with_dict(<this_table_to_replace_column, <dictionary_table>, <dictionary_from_field>, <dictionary_to_field>)
Словаря таблицы будет иметь от и к колонку, а функция может заменить все вхождения любого словаря из поля в его поле.
Я пытался сам, но не добился успеха. Вот что я делал до сих пор.
CREATE OR REPLACE FUNCTION replace_with_dict(to_replace VARCHAR,
dict_table regclass, from_field VARCHAR, to_field VARCHAR)
RETURNS VARCHAR AS $$
DECLARE
replaced VARCHAR;
dict_entry RECORD;
from_replace_pattern VARCHAR;
to_replace_pattern VARCHAR;
dictionary CURSOR FOR SELECT from_field AS "in", to_field AS "out" FROM basf_dict;
BEGIN
replaced := to_replace;
-- EXECUTE(format('SELECT %S, %S FROM %S;', from_field, to_field, dict_table)) IN dictionary;
FOR dic_entry IN dictionary LOOP
from_replace_pattern := ' ' || dic_entry."in" || ' ';
to_replace_pattern := ' ' || dic_entry."out" || ' ';
replaced := REPLACE(replaced, from_replace_pattern, to_replace_pattern);
END LOOP;
RETURN replaced;
END;
$$ LANGUAGE plpgsql
Когда я пытаюсь запустить описанную выше функцию в запросе, как это, replace_with_dict(p.nom_produto, "basf_dict", "de", "para"),
. Я получаю эту ошибку:
SQL Error [42703]: ERROR: column "basf_dict" does not exist
Posição: 86
org.postgresql.util.PSQLException: ERROR: column "basf_dict" does not exist
Posição: 86
EDIT 1:
Просто обратите внимание, что для переменной была опечатка. Я исправил, теперь моя функция декларации выглядит следующим образом:
CREATE OR REPLACE FUNCTION replace_with_dict(to_replace VARCHAR, dict_table VARCHAR, from_field VARCHAR, to_field VARCHAR)
RETURNS VARCHAR AS $$
DECLARE
replaced VARCHAR;
dict_entry RECORD;
from_replace_pattern VARCHAR;
to_replace_pattern VARCHAR;
-- dictionary CURSOR FOR SELECT from_field AS d_in, to_field AS d_out FROM basf_dict;
query text;
BEGIN
query := format('SELECT %I, %I FROM %I;', from_field, to_field, dict_table);
replaced := to_replace;
FOR dict_entry IN EXECUTE query LOOP
from_replace_pattern := ' ' || dic_entry.d_in || ' ';
to_replace_pattern := ' ' || dic_entry.d_out || ' ';
replaced := REPLACE(replaced, from_replace_pattern, to_replace_pattern);
END LOOP;
RETURN replaced;
END;
$$ LANGUAGE plpgsql
до сих пор не работает, теперь я получаю ошибку последующих при попытке выполнить запрос, который использует эту функцию:
SQL Error [42P01]: ERROR: missing FROM-clause entry for table "dic_entry"
Onde: PL/pgSQL function replace_with_dict(character varying,character varying,character varying,character varying) line 14 at assignment
org.postgresql.util.PSQLException: ERROR: missing FROM-clause entry for table "dic_entry"
Onde: PL/pgSQL function replace_with_dict(character varying,character varying,character varying,character varying) line 14 at assignment
EDIT 2:
для лучшего объяснения моей мотивации для создания функции, вот что я пытаюсь не делать:
SELECT
p.id,
p.nom_produto,
string_ranking_by_array(
REPLACE(
REPLACE(
p.nom_produto,
'FOS',
'FO'),
'S B',
'S_B'),
string_to_array(pe.nom_produto, ' ')
) AS ranking,
pe.nom_produto AS nom_pe,
pe.ean_produto,
pe.id AS id_pe
FROM
produto p, produto_empresa pe
WHERE 1 = 1
AND p.id_loja = 23
AND(p.ean_produto IS NULL OR p.ean_produto = '')
AND CHAR_LENGTH(cod_produto)= 12
AND cod_produto LIKE 'SC%'
ORDER BY
ranking DESC,
p.nom_produto
Я не хочу делать больше внутренних замен для каждого нового улучшения, которое я могу найти.
Первая: строковые константы нужны одинарные кавычки, а не двойные кавычки: https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS, а во-вторых: вы не можете использовать переменную в виде таблицы имя подобное. Для этого вам нужен динамический SQL. –