我只是有一个表格,其中包含国家列表及其ISO国家/地区代码.我将查询包装在存储过程(也称为函数)中,例如:
CREATE OR REPLACE FUNCTION get_countries(
) RETURNS setof record AS $$
SELECT country_code, country_name FROM country_codes
$$ LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
ERROR: a column definition list is required for functions returning "record"
Run Code Online (Sandbox Code Playgroud)
我知道我可以定义一个TYPE,然后像光标一样循环遍历记录集,但是在更新版本的PostgreSQL(我使用的是8.4.3)下,有更好的方法可以做到这一点,但我正在尝试要记住.
编辑:
这有效:
CREATE OR REPLACE FUNCTION get_countries(
) RETURNS setof country_codes AS $$
SELECT country_code, country_name FROM country_codes
$$ LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)
请注意"RETURNS setof [table name]".但它似乎并不是最灵活的.如果我尝试返回多个表的连接,它就会崩溃.
我正在使用PostgreSQL和pgAdmin,我无法使用触发器功能.但是,据我所知,你可以在PostgreSQL中返回类型触发器吗?
CREATE OR REPLACE FUNCTION validate_Cat()
RETURNS TRIGGER AS
$BODY$
BEGIN
-- CODE here
END;
$BODY$
LANGUAGE SQL;
CREATE TRIGGER validate_Cat
AFTER INSERT OR UPDATE ON Category
FOR EACH ROW execute procedure validate_Cat();
Run Code Online (Sandbox Code Playgroud) 我发现,默认情况下,PLPGSQL中数组的第一个索引从1开始,而不是像大多数编程语言一样.我只是好奇为什么会这样,以及其他编程语言是如何遵循这一点的?
谢谢!
我有一个PostgreSQL表,其中有一些索引的字段,并且必须是唯一的,以防止重复.这是由于PLPGSQL函数插入所有字段并捕获unique_violation异常,即使只有一个重复,它也会停止插入记录.
由于性能问题我不能做几个INSERT(其中一些是以数百个完成的),问题是它会停止所有进程,即使只有一个重复,就像下面示例中最火的两个值一样.
CREATE OR REPLACE FUNCTION easy_import() RETURNS VOID AS
$$
BEGIN
BEGIN
INSERT INTO things ("title", "uniq1", "uniq2") VALUES
('title 1', 100, 102),
('title 2', 100, 102),
('title 3', 101, 102),
('title 4', 102, 102),
('title 5', 103, 102),
('title 6', 104, 102),
('title 7', 105, 102),
('title 8', 106, 102),
('title 9', 107, 102),
('title 10', 108, 102);
RETURN;
EXCEPTION WHEN unique_violation THEN
-- do nothing
END;
END;
$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
有没有办法忽略一个记录的unique_violation并阻止它停止进一步的INSERT?
谢谢.
JOIN …如果满足某些条件,如何从PostgreSQL SQL语句中引发错误?
我试过下面的代码,但得到了错误.
CREATE OR REPLACE FUNCTION "exec"(text)
RETURNS text AS
$BODY$
BEGIN
EXECUTE $1;
RETURN $1;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
-- ERROR: syntax error at or near "raise"
-- LINE 1: raise 'test'
SELECT exec('raise ''test'' ') WHERE TRUE
Run Code Online (Sandbox Code Playgroud)
在实际应用TRUE中被某些条件所取代.
更新
我试图扩展答案以传递异常消息参数.尝试下面的代码,但语法错误.如何传递消息参数?
CREATE OR REPLACE FUNCTION exec(text, variadic )
RETURNS void LANGUAGE plpgsql AS
$BODY$
BEGIN
RAISE EXCEPTION $1, $2;
END;
$BODY$;
SELECT exec('Exception Param1=% Param2=%', 'param1', 2 );
Run Code Online (Sandbox Code Playgroud) 我有一个C#客户端应用程序,它使用Npgsql在PostgreSQL 9.1.4中调用plpgsql函数.该功能需要很长时间,我想以某种方式向客户报告进度.我该怎么做?
LISTEN/NOTIFY机制听起来很完美,除了整个事务在事务内部运行并且NOTIFY事件直到事务结束才发送,这对我来说是无用的.
我尝试过的另一件事是RAISE NOTICE,我可以在客户端上处理,但即使是那些通知似乎也会缓冲一段时间并分批发送.它总比没有好,但不理想.有什么方法可以"冲洗"它们,所以它们会立即发送给客户吗?
我有一个PostgreSQL函数来计算日期差异:
CREATE OR REPLACE FUNCTION testDateDiff () RETURNS int AS $BODY$
DECLARE startDate TIMESTAMP;
DECLARE endDate TIMESTAMP;
DECLARE diffDatePart int ;
BEGIN
Select evt_start_date From events Where evt_id = 5 INTO startDate ;
Select evt_start_date From events Where evt_id = 6 INTO endDate ;
SELECT EXTRACT(day FROM TIMESTAMP startDate - endDate) INTO diffDatePart;
RETURN diffDatePart;
END;
$BODY$
LANGUAGE plpgsql
COST 100
Run Code Online (Sandbox Code Playgroud)
如果直接减去日期,则计算差异.但在我的情况下,日期存在于变量as startDate和endDate,这会导致问题.
如何减去变量中包含的日期?
如果我有以下玩具查询
SELECT *
FROM my_tables
WHERE my_id in (
SELECT my_other_id
FROM my_other_tables
) AND some_slow_func(arg) BETWEEN 1 AND 2;
Run Code Online (Sandbox Code Playgroud)
WHERE子句中的第一个条件是否会短路第二个具有复杂运行时间的条件?
我正在研究一些实际上是plpgsql中FOR LOOP的一部分的sql,我可以对my_other_tables中存在的所有记录进行迭代,然后使用some_slow_func()在FOR LOOP的范围内进行测试.但我很好奇是否支持sql,或者plpgsql支持短路.
一些研究:我查看了Postgres的邮件列表,发现这说SQL一般不支持短路:
http://www.postgresql.org/message-id/171423D4-9229-4D56-B06B-58D29BB50A77@yahoo.com
但其中一个回复表明订单可以通过子选择来强制执行.我不确定他在说什么.我知道子选择是什么,但我不确定如何强制执行命令?有人可以为我澄清一下吗?
是否可以将postgres查询的结果作为输入传递给另一个函数?
作为一个非常人为的例子,说我有一个像
SELECT id, name
FROM users
LIMIT 50
Run Code Online (Sandbox Code Playgroud)
我想创建一个函数my_function,它接受第一个查询的结果集并返回最小的id.这可能在pl/pgsql中吗?
SELECT my_function(SELECT id, name FROM Users LIMIT 50); --returns 50
Run Code Online (Sandbox Code Playgroud) 我很茫然,我在我的本地Postgres服务器(postgres.app,Mac OS X 10.7)中创建存储过程时遇到问题,因此
$ psql
psql (9.3.0)
Type "help" for help.
dchaston=# CREATE OR REPLACE FUNCTION table_update()
dchaston-# RETURNS TRIGGER AS $$
dchaston$# BEGIN
dchaston$# NEW.last_edit = now();
dchaston$# RETURN NEW;
dchaston$# END;
dchaston$# $$ language 'plpgsql';
ERROR: could not access file "$libdir/plpgsql": No such file or directory
Run Code Online (Sandbox Code Playgroud)
我检查过以下内容:
语言安装:
dchaston=# select * from pg_language;
lanname | lanowner | lanispl | lanpltrusted | lanplcallfoid | laninline | lanvalidator | lanacl
---------+----------+---------+--------------+---------------+-----------+--------------+--------
internal | 10 | f | f | …Run Code Online (Sandbox Code Playgroud) plpgsql ×10
postgresql ×10
sql ×5
.net ×1
arrays ×1
datetime ×1
npgsql ×1
osx-lion ×1
postgres.app ×1