我有许多使用Postgres"Partitioning"功能的表.我想在每个表上定义一个常见的BEFORE INSERT OF ROW触发器,1)如果针对父表发生插入,则动态创建分区; 2)对分区重新执行插入.
就像是:
CREATE OR REPLACE FUNCTION partition_insert_redirect( )
RETURNS trigger AS $BODY$
BEGIN
... create the new partition and set up the redirect Rules ...
/* Redo the INSERT dynamically. The new RULE will redirect it to the child table */
EXECUTE 'INSERT INTO ' || quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME) ||
' SELECT NEW.*'
END
Run Code Online (Sandbox Code Playgroud)
但是在EXECUTE SQL中看不到"NEW"记录.我怎样才能尽可能简单地完成这项工作?
作为替代方案,我可以以某种方式迭代新记录中的字段吗?
我想过使用临时表:
EXECUTE 'CREATE TEMPORARY TABLE new_row (LIKE ' ||
quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME) ||
') ON …Run Code Online (Sandbox Code Playgroud) 我试图让这个plpgsql函数工作:
CREATE OR REPLACE FUNCTION outofdate(actualdate varchar)
RETURNS TABLE(designacion varchar(255),timebeingrotten varchar(255))
AS $BODY$
SELECT designacao, actualdate - prazo
FROM alimento
WHERE prazo < actualdate;
$BODY$
LANGUAGE 'plpgsql' volatile;
SELECT *
From outofdate('12/12/2012');
Run Code Online (Sandbox Code Playgroud)
它一直给我第2行的错误 - 表..
错误:"TABLE"或其附近的语法错误第2行:RETURNS TABLE(designacion varchar(255),timebeingrotten varch ...... ^
*** 错误 ***
错误:"TABLE"或其附近的语法错误SQL状态:42601字符:67
在当今,PostgreSQL 提供了大量的过程语言:pl/pgsql,pl/perl等
在用不同语言编写的程序中,速度/内存消耗是否有任何差异?
有人做过任何测试吗?
使用原生pl/pgsql是最正确的选择吗?
使用pl/*语言编写的用户函数的所有参数中,用C++编写并编译成可加载模块的过程有何不同?
我在PostgreSQL 9.2中有一个plpgsql函数,它返回一个表.该函数运行几个SELECT,返回与函数相同的列,然后返回这些结果或引发异常,具体取决于某些检查.我可以看到这样做的唯一方法是使用FOR ... LOOP,但我无法找到返回行的便捷方法.
我想做这样的事情:
CREATE OR REPLACE FUNCTION my_function()
RETURNS TABLE(column1 integer, column2 boolean, ...)
AS $BODY$
DECLARE
result_row RECORD;
BEGIN
FOR result_row IN (SELECT * FROM other_function_returning_same_columns()) LOOP
IF something_wrong_with(result_row) THEN
RAISE EXCEPTION 'Something went wrong';
END IF;
RETURN NEXT result_row;
END LOOP;
END
$BODY$ LANGUAGE plpgsql STABLE;
Run Code Online (Sandbox Code Playgroud)
这给了我一个错误:
错误:RETURN NEXT在OUT参数的功能中无法使用参数
我不确定为什么Postgres在这里抱怨,因为我的代码看起来很像文档中的示例,除了我的函数返回TABLE而不是SETOF.没有OUT参数.
我最终成功地使用了它
RETURN QUERY SELECT result_row.column1, result_row.column2, ...;
Run Code Online (Sandbox Code Playgroud)
但是必须一直列出所有列是丑陋的,难以维护.我相信一定有更好的方法.
与表或序列不同,无法通过pg_class找到用户定义的函数.上有问题是如何找到的所有功能的列表中删除或授予他们,而是如何找到一个单独的功能(具有已知的名称和参数类型)是不言自明从他们.那么如何找到一个函数是否存在?
编辑:我想以自动方式在函数中使用它.哪种解决方案性能最佳?陷阱错误是非常昂贵的,所以我想对我来说最好的解决方案是没有将错误转换为错误的额外步骤,但我可能在这个假设中错了.
我想直接从pgAdmin编辑器UI 执行一些pgScript.
FOR i IN 1..10 LOOP
PRINT i; -- i will take on the values 1,2,3,4,5,6,7,8,9,10 within the loop
END LOOP;
Run Code Online (Sandbox Code Playgroud)
但我总是得到
[ERROR ] 1.0: syntax error, unexpected character
Run Code Online (Sandbox Code Playgroud)
我也尝试用do $$ ... $$包装代码,但是没有解决问题.
我的最后一个问题将数组传递给存储到postgres有点不清楚.现在,澄清我的目标:
我想创建一个Postgres存储过程,它将接受两个输入参数.一个将是一些数量的列表,例如(100, 40.5, 76),另一个将是一些发票的 列表('01-2222-05','01-3333-04','01-4444-08').之后我想使用这两个数字和字符列表并对它们做一些事情.例如,我想从这一组数字中取出每个金额,并将其分配给相应的发票.
在Oracle中类似的东西看起来像这样:
SOME_PACKAGE.SOME_PROCEDURE (
789,
SYSDATE,
SIMPLEARRAYTYPE ('01-2222-05','01-3333-04','01-4444-08'),
NUMBER_TABLE (100,40.5,76),
'EUR',
1,
P_CODE,
P_MESSAGE);
Run Code Online (Sandbox Code Playgroud)
当然,这两种类型SIMPLEARRAYTYPE,并NUMBER_TABLE出现在靠前的DB定义.
使用PostgreSQL 9.0.
比方说,我有一个包含字段的表:company,profession和year.我想返回一个包含独特公司和专业的结果,但基于数字序列聚合(到一个数组中很好)年份:
示例表:
+-----------------------------+
| company | profession | year |
+---------+------------+------+
| Google | Programmer | 2000 |
| Google | Sales | 2000 |
| Google | Sales | 2001 |
| Google | Sales | 2002 |
| Google | Sales | 2004 |
| Mozilla | Sales | 2002 |
+-----------------------------+
Run Code Online (Sandbox Code Playgroud)
我对一个输出类似于以下行的查询感兴趣:
+-----------------------------------------+
| company | profession | year |
+---------+------------+------------------+
| Google | Programmer | [2000] |
| …Run Code Online (Sandbox Code Playgroud) 我正在使用PostgreSQL数据库中的PL/pgSQL函数来解决死锁问题.请在代码块中找到SQL语句(只是示例):
BEGIN
UPDATE accounts SET balance = 0 WHERE acct_name like 'A%';
UPDATE accounts SET balance = balance + 100 WHERE acct_name like '%A';
EXCEPTION WHEN OTHERS THEN RAISE NOTICE SQLERRM;
END;
Run Code Online (Sandbox Code Playgroud)
我发现在这个语句运行期间发生了死锁.但我不确定是否有其他语句试图同时更新此表(因为我在我的日志记录系统中没有找到任何语句).
那么,这句话中是否可能出现死锁?据我所知,如果我们用BEGIN/ 阻止整个陈述END.将有相同的交易,不应自行锁定.
我的工作产生像在回答#2随机IDS系统上这里.
我的问题是,提到的pseudo_encrypt()函数适用于int而不是bigint.我试图重写它,但它返回总是相同的结果:
CREATE OR REPLACE FUNCTION pseudo_encrypt(VALUE bigint) returns bigint AS $$
DECLARE
l1 bigint;
l2 int;
r1 bigint;
r2 int;
i int:=0;
BEGIN
l1:= (VALUE >> 32) & 4294967296::bigint;
r1:= VALUE & 4294967296;
WHILE i < 3 LOOP
l2 := r1;
r2 := l1 # ((((1366.0 * r1 + 150889) % 714025) / 714025.0) * 32767)::int;
l1 := l2;
r1 := r2;
i := i + 1;
END LOOP;
RETURN ((l1::bigint << 32) + r1); …Run Code Online (Sandbox Code Playgroud)