函数可以作为匿名函数直接存储在列中作为其值吗?
假设我想将此函数存储在列中.示例(伪代码):
表my_table:pk(int),my_function(func)
func(x){return x*100}
后来用它作为:
select
t.my_function(some_input) AS output
from
my_table as t
where t.pk = 1999
Run Code Online (Sandbox Code Playgroud)
每个pk的功能可能不同.
我的PostgreSQL数据库包含一个用于存储已注册实体实例的表.此表格通过电子表格上传填充.Web界面允许操作员修改所呈现的信息.但是,原始数据不会被修改.所有的改变都存储在一个单独的表changes与列unique_id,column_name,value和updated_at.
更改完成后,首先查询原始表,然后查询更改表(使用实例ID和最新更改日期,按列名称分组),将其呈现给操作员.这两个结果在PHP中合并,并在Web界面上显示.这是执行任务的一种相当严格的方式,我想将所有逻辑保留在SQL中.
我可以使用以下查询轻松选择表的最新更改:
SELECT fltr_chg.unique_id, fltr_chg.column_name, chg_val.value
FROM changes AS chg_val
JOIN (
SELECT chg_rec.unique_id, chg_rec.column_name, MAX( chg_rec.updated_at )
FROM information_schema.columns AS source
JOIN changes AS chg_rec ON source.table_name = 'instances'
AND source.column_name = chg_rec.column_name
GROUP BY chg_rec.unique_id, chg_rec.column_name
) AS fltr_chg ON fltr_chg.unique_id = chg_val.unique_id
AND fltr_chg.column_name = chg_val.column_name;
Run Code Online (Sandbox Code Playgroud)
从instances表中选择条目同样简单:
SELECT * FROM instances;
Run Code Online (Sandbox Code Playgroud)
现在,如果只有一种方法可以转换前一个结果并将结果值替换为后者,基于unique_id和column_name,并且仍将结果保留为表格,则问题将得到解决.这可能吗?
我确信这不是最罕见的问题,而且很有可能,某些系统会以类似的方式跟踪数据的变化.如果不是通过上述方法之一(当前和寻求的解决方案),他们如何将它们应用于数据?
这个问题与前面的问题有关:为什么从关系数据库中不支持的存储过程中进行选择?
在SQL Server,则无法执行连接(或从选择)存储过程(请注意:一个存储过程是从一个完全不同的功能(在SQL Server术语表值函数) -一个功能,你知道列在设计时返回,但是使用一个过程,直到运行时才知道要返回的特定列).
对于SQL Server,确实存在"DBA通常不允许"的方法,可以实现这样的连接:OPENROWSET
所以问题是:
PostgreSQL可以在两个程序之间执行连接,直到运行时才能知道这些列吗?
它可以做同样的事情,除了使用驻留在外部第三方数据库中的存储过程(可能通过外部数据包装器或其他一些机制)?
我想创建一个函数,尝试将一组值转换为用户指定的类型(默认为文本)。一个非常简单的函数如下所示:
CREATE OR REPLACE FUNCTION cast_to(variable jsonb, key text, target_type anyelement DEFAULT 'TEXT'::regtype) RETURNS anyelement as $$
begin
RETURN CAST(variable->>key AS target_type);
end
$$
language plpgsql;
Run Code Online (Sandbox Code Playgroud)
我已经尝试过以下方法:
SELECT CAST('foo' AS 'text');: 给出语法错误SELECT CAST('foo' AS 'text'::regtype);: 与 1 相同的错误SELECT CAST('foo' AS pg_typeof(null::text));说type pg_typeof does not exist 最后一次尝试是我可以传入一个具有目标类型的变量而不是文本表示形式。使用该函数将如下所示SELECT cast_to('text', NULL::text);。
如何实现这个或类似的功能?
编辑:正如评论中所建议的,我尝试使用动态 SQL。我运气不太好。我创建了一个非常基本的案例,不使用任何变量:
CREATE OR REPLACE FUNCTION audit.cast_to() RETURNS text as $$
DECLARE
_sql TEXT := 'SELECT CAST($1 AS $2)';
out TEXT;
begin …Run Code Online (Sandbox Code Playgroud) postgresql ×4
dynamic-sql ×3
plpgsql ×2
sql ×2
crosstab ×1
database ×1
php ×1
polymorphism ×1
sql-server ×1