我是数据库开发的新手,所以我对以下示例有些怀疑:
函数f1() - 语言sql
create or replace function f1(istr varchar) returns text as $$
select 'hello! '::varchar || istr;
$$ language sql;
Run Code Online (Sandbox Code Playgroud)
函数f2() - 语言plpgsql
create or replace function f2(istr varchar)
returns text as $$
begin select 'hello! '::varchar || istr; end;
$$ language plpgsql;
Run Code Online (Sandbox Code Playgroud)
这两个函数都可以像select f1('world')或一样调用select f2('world').
如果我打电话select f1('world')的输出将是:
`hello! world`
Run Code Online (Sandbox Code Playgroud)并输出为select f2('world'):
错误:查询没有结果数据的目的地提示:如果要丢弃SELECT的结果,请改用PERFORM.语境:在SQL语句中PL/pgSQL函数f11(字符变化)第2行 ******错误******
我想知道的差异,在哪些情况下我应该使用language sql或language plpgsql …
我有Postgresql函数,它必须将大约150万个数据插入表中.我想要的是我希望看到每个记录插入填充表格.目前当我尝试使用大约1000条记录时会发生什么,只有在完成函数执行后才会填充get.如果我在中途停止功能,则不会填充任何数据.即使在插入了一定数量的记录后停止,我怎样才能提交记录?
我已经编写了一个自动化功能,如下所述,它根据一些规则调用其他一些功能.该函数给出了我想要的结果,但我面临的问题是它在内部处理每个函数后都没有提交数据.一旦主要功能完成,它就会提交整个数据.我想做一个内部事务,它应该在内部函数执行完成时提交数据.我尝试在每个PERFORM语句之后给出一个COMMIT语句,但是我收到一个错误,说"无法在PL/pgSQL中开始/结束事务".
任何人都可以建议我如何在函数内部进行事务处理.
CREATE OR REPLACE FUNCTION ccdb.fn_automation_for_updation()
RETURNS void AS
$BODY$
DECLARE
sec_col refcursor;
cnt integer;
sec_code ccdb.update_qtable%ROWTYPE;
new_cnt integer;
BEGIN
SELECT COUNT(*)
INTO cnt
FROM ccdb.update_qtable
WHERE status_flag IN (-1,1);
OPEN sec_col FOR
SELECT * FROM ccdb.update_qtable WHERE status_flag IN (-1,1);
FOR i IN 1..cnt
LOOP
FETCH sec_col INTO sec_code;
PERFORM ccdb.o_dtr_update(sec_code.section_code);
PERFORM ccdb.o_consumer_update_for_update(sec_code.section_code);
PERFORM ccdb.o_consumer_update_for_insert(sec_code.section_code);
PERFORM ccdb.o_bills_update_for_update(sec_code.section_code);
PERFORM ccdb.o_bills_update_for_insert(sec_code.section_code);
PERFORM ccdb.o_payments_update_for_update_new(sec_code.section_code);
PERFORM ccdb.o_payments_update_for_insert(sec_code.section_code);
PERFORM ccdb.o_payments_map_update_for_update(sec_code.section_code);
PERFORM ccdb.o_payments_map_update_for_insert(sec_code.section_code);
SELECT COUNT(*) INTO new_cnt FROM ccdb.update_qtable WHERE status_flag IN (-1,1);
IF …Run Code Online (Sandbox Code Playgroud) 我有一些关于 postgres 功能和事务如何工作的问题。
目前我的功能是这样的:
CREATE OR REPLACE FUNCTION test_function(some_id character varying)
RETURNS character varying AS
$BODY$
BEGIN
S1;
S2;
S3;
.
.
Sn;
RETURN some_id;
END; $BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Run Code Online (Sandbox Code Playgroud)
这些语句可以是INSERT,也可以是基于 的UPDATE普通SELECT查询some_id。正如我从 postgre文档中了解到的,此函数中的所有语句都作为单个事务执行并在 END 处提交。
我的问题是:
S1成功但S2 失败了,会S1承诺吗?BEGIN都作为单个事务执行,对吗?COMMITbeforeEND并且所有语句都成功的情况下,无论 autocommit = on/off 是否都会提交事务?S1, S2, S3都是INSERT陈述。S1并且S2成功但S3失败, …我想以这种方式在PL / pgSQL存储过程中使用dblink:
PERFORM dblink_exec('myconn', 'BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE');
PERFORM dblink_exec('myconn', 'SELECT another_stored_procedure()');
PERFORM dblink_exec('myconn', 'COMMIT');
Run Code Online (Sandbox Code Playgroud)
但是在运行时出现错误:
ERROR: statement returning results not allowed
CONTEXT: SQL statement "SELECT dblink_exec('myconn', 'select another_stored_procedure()')"
Run Code Online (Sandbox Code Playgroud)
因此执行失败,尽管我尝试以其他方式获得所需的结果。
更新1:
我知道Postgresql中的存储过程是事务性的。我将dblink用于自治事务功能以在同一服务器上使用它。
问题是服务器上的默认事务级别是“读已提交”,但有时我需要从另一个级别开始事务,例如“可序列化”。
因此,我需要在具有明确事务级别指定的自主事务中执行存储过程。
据我所知dblink允许这样做,但是我找不到适合我情况的有关dblink或dblink_exec函数的任何有用信息。