Postgresql 以文本字符串形式访问给定字段名的postgres字段
我在postgres有一个表:Postgresql 以文本字符串形式访问给定字段名的postgres字段,postgresql,Postgresql,我在postgres有一个表: create table fubar ( name1 text, name2 text, ..., key integer); 我想编写一个函数,在给定列名的情况下从fubar返回字段值: function getFubarValues(col_name text, key integer) returns text ... 其中,getFubarValues返回键标识的行中指定列的值。看起来这应该很容易 我不知所措。有人能帮忙吗?谢谢。您可以使用动态SQL按
create table fubar (
name1 text,
name2 text, ...,
key integer);
我想编写一个函数,在给定列名的情况下从fubar返回字段值:
function getFubarValues(col_name text, key integer) returns text ...
其中,getFubarValues返回键标识的行中指定列的值。看起来这应该很容易
我不知所措。有人能帮忙吗?谢谢。您可以使用动态SQL按名称选择列:
create or replace function get_fubar_values (col_name text, row_key integer)
returns setof text language plpgsql as $$begin
return query execute 'select ' || quote_ident(col_name) ||
' from fubar where key = $1' using row_key;
end$$;
Klin的回答是一个很好的(即安全的)解决问题的方法,但可以简化:
PostgreSQL的->
运算符允许表达式。例如:
CREATE TABLE test (
id SERIAL,
js JSON NOT NULL,
k TEXT NOT NULL
);
INSERT INTO test (js,k) VALUES ('{"abc":"def","ghi":"jkl"}','abc');
SELECT js->k AS value FROM test;
产生
value
-------
"def"
因此,我们可以将其与行到行json
相结合:
CREATE TABLE test (
id SERIAL,
a TEXT,
b TEXT,
k TEXT NOT NULL
);
INSERT INTO test (a,b,k) VALUES
('foo','bar','a'),
('zip','zag','b');
SELECT row_to_json(test)->k AS value FROM test;
产生:
value
-------
"foo"
"zag"
在这里,我从表本身获取键,但当然可以从任何源/表达式获取。这只是一个价值。还要注意,返回的结果是一个JSON值类型(它不知道是文本、数字还是布尔值)。如果希望它是文本,只需将其强制转换为:(row\u to\u json(test)->k)::text
现在问题本身已经得到了回答,下面是为什么你不应该这样做,以及你应该做什么! 永远不要相信任何数据。即使它已经存在于您的数据库中,您也不应该相信它。我在这里发布的方法是安全的,可以抵御SQL注入攻击,但是攻击者仍然可以将
k
设置为'id'
,并看到一列他们不想看到的内容
一种更好的方法是在考虑这种查询的情况下构造数据。Postgres为此提供了一些优秀的数据类型;HSTORE和JSON/JSONB。将动态列合并到一个具有这些类型之一的列中(我建议HSTORE更简单、更完整)
这有几个优点:您的模式定义良好,如果添加更多的动态列,则不需要更改,不需要执行昂贵的重新转换(即行到行json
),并且可以利用列上的索引(多亏了PostgreSQL的功能索引)
与我上面写的代码等效的代码是:
CREATE EXTENSION HSTORE; -- necessary if you're not already using HSTORE
CREATE TABLE test (
id SERIAL,
cols HSTORE NOT NULL,
k TEXT NOT NULL
);
INSERT INTO test (cols,k) VALUES
('a=>"foo",b=>"bar"','a'),
('a=>"zip",b=>"zag"','b');
SELECT cols->k AS value FROM test;
或者,为了在插入时自动转义值,可以使用以下方法之一:
INSERT INTO test (cols,k) VALUES
(hstore( 'a', 'foo' ) || hstore( 'b', 'bar' ), 'a'),
(hstore( ARRAY['a','b'], ARRAY['zip','zag'] ), 'b');
有关更多详细信息,请参阅。“这将从给定列名的fubar返回字段值”-为什么不能直接编写
从fubar选择列名?您在这里试图解决的真正问题是什么?这可能比Kill的答案要快,但OP应该注意,在使用此方法之前,他们必须注意列名是安全的(任何空格、引号或其他特殊字符都会将其打断,如果col_name输入不可信(即,它来自用户或数据库本身,这在本问题的上下文中似乎很可能),则这是SQL注入风险)