我想知道是否有可能创建一个SQL函数来对待参数行,就像它是“鸭型”一样。也就是说,我希望能够传递具有特定公用列名称的不同表或视图中的行,并在该函数内的这些列上进行操作。在SQL函数中虚拟化列
这里是一个非常简单的例子,试图说明问题:
=> CREATE TABLE tab1 (
id SERIAL PRIMARY KEY,
has_desc BOOLEAN,
x1 TEXT,
description TEXT
);
CREATE TABLE
=> CREATE FUNCTION get_desc(tab tab1) RETURNS TEXT AS $$
SELECT CASE tab.has_desc
WHEN True THEN
tab.description
ELSE
'Default Description'
END;
$$ LANGUAGE SQL;
=> INSERT INTO tab1 (has_desc, x1, description) VALUES (True, 'Foo', 'FooDesc');
INSERT 0 1
=> INSERT INTO tab1 (has_desc, x1, description) VALUES (True, 'Bar', 'BarDesc');
INSERT 0 1
=> SELECT get_desc(tab1) FROM tab1;
get_desc
----------
BarDesc
FooDesc
(2 rows)
这当然是非常做作。实际上,我的表格有更多的字段,功能更复杂。
现在我想添加其他表/视图并将它们传递给相同的函数。新的表/视图具有不同的列,但函数将关心的列对于所有这些列是通用的。为了增加简单的例子,我想补充这两个表:
CREATE TABLE tab2 (
id SERIAL PRIMARY KEY,
has_desc BOOLEAN,
x2 TEXT,
description TEXT
);
CREATE TABLE tab3 (
id SERIAL PRIMARY KEY,
has_desc BOOLEAN,
x3 TEXT,
description TEXT
);
注意三个有has_desc
和description
字段是get_desc
实际使用的唯一的。不过,当然,如果我尝试使用现有的功能与tab2
,我得到:
=> select get_desc(tab2) FROM tab2;
ERROR: function get_desc(tab2) does not exist
LINE 1: select get_desc(tab2) FROM tab2;
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
我希望能够定义一个共同的功能,做同样的事情get_desc
但需要作为参数,从任何一个排的三张桌子。有没有办法做到这一点?
或者,还有一种方法可以将整行转换为仅包含一组定义的字段的常见行类型吗?
(我知道我可以改变函数的参数,只是采取XX.has_desc
和XX.description
,但我试图找出是哪个字段的函数内部使用,而不需要扩大这些在每一个地方的函数被调用。)
我会很感激的例子。看起来,这将等同于扩展函数参数以包含函数将在其上运行的所有字段 - 如果必须在每次调用之前添加一个附加的WITH子句。 –
确实如此,但就代码而言,混乱将与主查询分离。另外,使用通用模式创建每个表的VIEW也将摆脱'WITH'子句。视图可以在函数附近定义。 –