如何?
举个简单的例子.我有一个简单的功能:
DO LANGUAGE plpgsql $$ DECLARE
BEGIN
EXECUTE 'SELECT NOW()';
END $$;
Run Code Online (Sandbox Code Playgroud)
我如何从匿名函数返回"NOW()"或其他值的值?该函数作为一个例子我有一个更复杂的功能.
我试图从带有2个OUT参数的plpgsql函数中获取值,但是我遇到了一些问题.
这些是功能:
CREATE OR REPLACE FUNCTION get_test(OUT x text, OUT y text)
AS $$
BEGIN
x := 1;
y := 2;
END;
$$ LANGUAGE plpgsql;
----------------------------------------------------------------
CREATE OR REPLACE FUNCTION get_test_read()
RETURNS VOID AS $$
DECLARE
xx text;
yy text;
BEGIN
SELECT get_test() INTO xx, yy;
RAISE INFO 'x: <%>', xx;
RAISE INFO 'y: <%>', yy;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
命令的输出:
select get_test_read();
信息:x:<(1,2)
信息:y:<>
get_test_read
所以这两个值都转到第一个参数.我找不到一些关于如何调用这样的函数的例子.
我有一个用作INSERT触发器的函数.此函数删除与正在插入的行中的[序列号]冲突的行.它工作得很漂亮,所以我真的不想辩论这个概念的优点.
DECLARE
re1 feeds_item.shareurl%TYPE;
BEGIN
SELECT regexp_replace(NEW.shareurl, '/[^/]+(-[0-9]+\.html)$','/[^/]+\\1') INTO re1;
RAISE NOTICE 'DELETEing rows from feeds_item where shareurl ~ ''%''', re1;
DELETE FROM feeds_item where shareurl ~ re1;
RETURN NEW;
END;
Run Code Online (Sandbox Code Playgroud)
我想在NOTICE中添加一个指示有多少行受影响(也就是:已删除).我该怎么做(使用LANGUAGE'plpgsql')?
更新: 基于"厨房里的鸡肉"的一些出色指导,我将其更改为:
DECLARE
re1 feeds_item.shareurl%TYPE;
num_rows int;
BEGIN
SELECT regexp_replace(NEW.shareurl, '/[^/]+(-[0-9]+\.html)$','/[^/]+\\1') INTO re1;
DELETE FROM feeds_item where shareurl ~ re1;
IF FOUND THEN
GET DIAGNOSTICS num_rows = ROW_COUNT;
RAISE NOTICE 'DELETEd % row(s) from feeds_item where shareurl ~ ''%''', num_rows, re1;
END IF;
RETURN NEW;
END;
Run Code Online (Sandbox Code Playgroud) 在T-SQL中有什么类似表变量的吗?
在Sql Server中,它看起来像这样:
DECLARE @ProductTotals TABLE
(
ProductID int,
Revenue money
)
Run Code Online (Sandbox Code Playgroud)
然后在程序中我可以:
INSERT INTO @ProductTotals (ProductID, Revenue)
SELECT ProductID, SUM(UnitPrice * Quantity)
FROM [Order Details]
GROUP BY ProductID
Run Code Online (Sandbox Code Playgroud)
并像普通表一样操纵这个变量.
对于安全性敏感的设计,我想禁用DELETEs某些表.
所述DELETE应该仅设置一个deleted上的行(这将是然后在视图,这将被本应用层可以使用可见)标志.
据我所知,规则会生成其他查询 - 因此规则无法抑制原始查询.
举例说明带触发器的玩具示例(尚未测试):
-- data in this table should be 'undeletable'
CREATE table article (
id serial,
content text not null,
deleted boolean default false
)
-- some view that would only show articles, that are NOT deleted
...
-- toy trigger (not tested)
CREATE OR REPLACE FUNCTION suppress_article_delete()
RETURNS TRIGGER AS $sad$
BEGIN
IF (TG_OP = 'DELETE') THEN
UPDATE article SELECT id, content, TRUE;
-- NEW or NULL?? …Run Code Online (Sandbox Code Playgroud) 我试图crosstab在PostgreSQL中创建查询,以便它自动生成crosstab列而不是硬编码.我编写了一个函数,可以动态生成我的crosstab查询所需的列列表.我们的想法是crosstab使用动态sql 在查询中替换此函数的结果.
我知道如何在SQL Server中轻松完成这项工作,但我对PostgreSQL的了解有限,阻碍了我在这方面的进展.我正在考虑将生成动态列列表的函数结果存储到变量中,并使用它来动态构建sql查询.如果有人可以指导我这样做会很棒.
-- Table which has be pivoted
CREATE TABLE test_db
(
kernel_id int,
key int,
value int
);
INSERT INTO test_db VALUES
(1,1,99),
(1,2,78),
(2,1,66),
(3,1,44),
(3,2,55),
(3,3,89);
-- This function dynamically returns the list of columns for crosstab
CREATE FUNCTION test() RETURNS TEXT AS '
DECLARE
key_id int;
text_op TEXT = '' kernel_id int, '';
BEGIN
FOR key_id IN SELECT DISTINCT key FROM test_db ORDER BY key LOOP …Run Code Online (Sandbox Code Playgroud) 我有一个表模式,其中包含一个int数组列,以及一个自定义聚合函数,它对数组内容求和.换句话说,给出以下内容:
CREATE TABLE foo (stuff INT[]);
INSERT INTO foo VALUES ({ 1, 2, 3 });
INSERT INTO foo VALUES ({ 4, 5, 6 });
Run Code Online (Sandbox Code Playgroud)
我需要一个可以返回的"sum"函数{ 5, 7, 9 }.正确运行的PL/pgSQL版本如下:
CREATE OR REPLACE FUNCTION array_add(array1 int[], array2 int[]) RETURNS int[] AS $$
DECLARE
result int[] := ARRAY[]::integer[];
l int;
BEGIN
---
--- First check if either input is NULL, and return the other if it is
---
IF array1 IS NULL OR array1 = '{}' THEN
RETURN array2;
ELSEIF …Run Code Online (Sandbox Code Playgroud) 我试图从PostgreSQL触发器函数发出通知.我可以成功使用NOTIFY命令,但我没有运气pg_notify.即使我从psql控制台调用pg_notify函数时收到通知,但在从触发器函数调用它时,我从未收到通知.
此版本的触发器功能按预期工作.我有一个听到'mymessage'的Java程序,它收到一个带有'NOTIFY'有效负载的通知.
-- Function: conversation_notify()
-- DROP FUNCTION conversation_notify();
CREATE OR REPLACE FUNCTION conversation_notify()
RETURNS trigger AS
$BODY$
BEGIN
--SELECT pg_notify('mymessage', 'fired by FUNCTION');
NOTIFY mymessage, 'fired by NOTIFY';
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION conversation_notify() OWNER TO postgres;
Run Code Online (Sandbox Code Playgroud)
此版本的触发器功能无法按预期工作.唯一的变化是取消注释pg_notify行并注释掉下面的NOTIFY行.(我没有修改LISTENing的Java应用程序.)我希望我的应用程序LISTENing到'mymessage'应该收到'FUNCTION'有效负载的通知.实际行为是在修改相应表后30秒甚至没有收到任何内容.
-- Function: conversation_notify()
-- DROP FUNCTION conversation_notify();
CREATE OR REPLACE FUNCTION conversation_notify()
RETURNS trigger AS
$BODY$
BEGIN
SELECT pg_notify('mymessage', 'fired by FUNCTION');
--NOTIFY mymessage, 'fired by NOTIFY';
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql …Run Code Online (Sandbox Code Playgroud) 在标记ALTER TABLE的pgsql事件触发器中,我希望知道正在更改哪个表.
pg变量不包括这一点,GET STACKED DIAGNOSTICS也没有暴露变量.
有了可用的变量,触发器函数本身是否有任何方法可以查看负责启动该函数的SQL命令的文本.
例如,如果
ALTER TABLE base1 ADD COLUMN col1 int;
Run Code Online (Sandbox Code Playgroud)
负责调用事件触发器,是否有任何方式在事件触发器中查看ALTER TABLE base1 ADD COLUMN col1 int文本本身?
写入PL/pgSQL或SQL可定义为的函数RETURNS void.我最近偶然发现了结果的奇怪差异.
请考虑以下演示:
CREATE OR REPLACE FUNCTION f_sql()
RETURNS void AS
'SELECT NULL::void' -- "do nothing", no special meaning
LANGUAGE sql;
CREATE OR REPLACE FUNCTION f_plpgsql()
RETURNS void AS
$$
BEGIN
NULL; -- "do nothing", no special meaning
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
该函数f_sql()使用唯一可能的方法SELECT(在SQL函数中作为最后一个命令)RETURNS void.我使用它只是因为它是用于此测试目的的最简单方法 - 任何其他函数,例如,UPDATE或者DELETE显示相同的行为.
现在,void是一种虚构的类型.虽然plpgsql功能似乎返回一个空字符串类型相当于void有效,''::void.该sql功能似乎回归NULL::void.
db=# SELECT f_sql() IS NULL; …Run Code Online (Sandbox Code Playgroud) plpgsql ×10
postgresql ×10
triggers ×4
arrays ×1
audit ×1
c ×1
crosstab ×1
database ×1
dynamic-sql ×1
null ×1
sql ×1
sql-delete ×1
void ×1