クライアントは何かを別のテーブルに保存しようとしています。 (ロングストーリー、それは必需品です)。 これを行うには、独自の名前空間で新しいテーブルを作成するPostgres関数を構築しました。PostgreSQL - 動的テーブル、関数内のテキスト配列から値を挿入
これらの表は、2,4、または100の列を持つことができます。 問題はありませんが、これは機能します。これらの動的表の使用されるデータ型は、ネイティブです(例:テキスト、ブーリアン、整数など。
問題が発生しました。これらのテーブルにデータを挿入する必要があります。ポイントは、ユーザーがテーブルに直接アクセスすることはできません、彼らは機能を通じてこれを行うでしょう。
これは問題ではありませんが、テキストデータ型では問題があります。
-- Function: add(integer, text[])
-- DROP FUNCTION add(integer, text[]);
CREATE OR REPLACE FUNCTION add(id integer, fields text[])
RETURNS integer AS
$BODY$
DECLARE
l_line_ending text := ')';
l_fieldtype integer;
l_ito_table_name text;
l_ito_fieldnames text;
l_field ito_fields%rowtype;
l_first_loop boolean := true;
l_values_to_insert text := 'VALUES (';
l_loop_counter integer := 0;
l_query text;
BEGIN
select into l_ito_table_name ito_table_name from ito where id = target_ito_id;
l_ito_fieldnames := 'insert into ' || l_ito_table_name || '(';
FOR l_field IN SELECT * FROM ito_fields
WHERE ito_fields.ito_id = target_ito_id
order by ito_fields.id asc
LOOP
l_loop_counter := l_loop_counter +1;
l_fieldtype := l_field.fieldtype;
if not l_first_loop THEN
l_values_to_insert := (l_values_to_insert || ', ');
end if;
if l_field.fieldtype = 1 THEN
l_values_to_insert := (l_values_to_insert || '''' || (fields[l_loop_counter]) || '''');
elsif l_field.fieldtype = 2 THEN
l_values_to_insert := quote_literal(l_values_to_insert || private.cast_to_integer(fields[l_loop_counter]));
elsif l_field.fieldtype = 3 THEN
l_values_to_insert := quote_literal(l_values_to_insert || private.cast_to_boolean(fields[l_loop_counter]));
elsif l_field.fieldtype = 4 THEN
l_values_to_insert := quote_literal(l_values_to_insert || private.cast_to_float(fields[l_loop_counter]));
else
return 103;
end if;
if l_first_loop then
l_ito_fieldnames := l_ito_fieldnames || l_field.column_name;
l_first_loop := false;
else
l_ito_fieldnames := l_ito_fieldnames || ', ' || l_field.column_name;
end if;
END LOOP;
l_ito_fieldnames := l_ito_fieldnames || l_line_ending;
l_values_to_insert := ((l_values_to_insert) || (l_line_ending));
l_query := (l_ito_fieldnames || l_values_to_insert);
EXECUTE l_query;
return 0;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION add(integer, text[])
OWNER TO postgres;
表は店舗すべてのフィールドのメタデータをito_fields、そのデータ型は、バージョンは、説明はここに格納されています。ここでは
は、今までの関数です。 itoテーブルには、すべての動的テーブルデータが格納されます。この機能のポイントは引用符です。 insert関数は動的に作成されるので、insert関数のテキストフィールドの前後に引用符を追加する必要があります。 Postgresはすぐにエラーを出しています。 quote_literal関数でさえ、文字列の連結のためにまだ問題です(私はセキュリティ上のリスクがあることは知っていますが、今のところ問題ありません)。
私はquote_literal、quote_identを使用しようとしましたが、実行関数(replace(query、l_quote_rep、 '' ''))まで引用符( ')を置き換えても。 。。手がかり今どのようにこの問題を解決するには...事前に
おかげ
0は標準の「成功」コードです。 正しいデータ型へのキャストがいくつかありません。アイデアは、すべてのフィールドがテキストとして挿入されるのではなく、そのネイティブデータ型に挿入されるということです。 (現在サポートされている:テキスト、整数、ブール、倍精度)。 (現時点でテストする可能性はありません) – Reneger
原則として、テキストから他のデータ型へのキャストが存在する必要があります。 – filiprem