为我的数据库执行以下方案:
create sequence data_sequence;
create table data_table
{
id integer primary key;
field varchar(100);
};
create view data_view as
select id, field from data_table;
create function data_insert(_new data_view) returns data_view as
$$declare
_id integer;
_result data_view%rowtype;
begin
_id := nextval('data_sequence');
insert into data_table(id, field) values(_id, _new.field);
select * into _result from data_view where id = _id;
return _result;
end;
$$
language plpgsql;
create rule insert as on insert to data_view do instead
select data_insert(new);
Run Code Online (Sandbox Code Playgroud)
然后输入psql:
insert into data_view(field) values('abc');
Run Code Online (Sandbox Code Playgroud)
想看到类似的东西: …
基本上,至少为了概念验证,我想要一个我可以运行的函数:SELECT res('table_name'); 这将给我SELECT*FROM table_name;的结果.我遇到的问题是架构......在我所拥有的函数的声明中:
创建或替换功能res(table_name TEXT)返回设置此THEPISEPEPROBLEM AS
问题是我不知道如何声明我的返回,因为它要我指定一个表或一个模式,在实际运行该函数之前我不会这样做.
有任何想法吗?
我有一个自定义类型:
create type some_type as (
some_bool_param boolean,
str varchar
);
Run Code Online (Sandbox Code Playgroud)
我用这种类型的字段创建一个表并插入一些数据:
create table test_table (
strs some_type
);
insert into test_table(strs) values
((false, 'First str'))
, ((false, 'Second str '))
, ((false, 'Third str'))
, ((false, 'Yet another str'));
Run Code Online (Sandbox Code Playgroud)
现在我尝试返回 setofsome_type数据:
create or replace function get_str() returns setof some_type as
$$
declare
r some_type;
begin
for r in
select * from test_table loop
return next r;
end loop;
return;
end;
Run Code Online (Sandbox Code Playgroud)
我打电话get_str():
select * from get_str(); …Run Code Online (Sandbox Code Playgroud) 我想在PostgreSQL中做这样的事情.
我试过这个:
CREATE or replace FUNCTION create_patient(_name text, _email text, _phone text
, _password text
, _field1 text, _field2 text, _field3 timestamp, _field4 text
, OUT _pid integer, OUT _id integer
) RETURNS record AS
$$
DECLARE
_id integer;
_type text;
_pid integer;
BEGIN
_type := 'patient';
INSERT into patients (name, email, phone, field1, field2, field3)
VALUES (_name, _email, _phone, _field1, _field2, _field3)
RETURNING id into _pid;
INSERT into users (username, password, type, pid, phone, language)
VALUES (_email, …Run Code Online (Sandbox Code Playgroud) 我试着编写简单的函数:
CREATE OR REPLACE FUNCTION add_mail_settings_column() RETURNS void AS $$
BEGIN
asd text := 'asd';
END $$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
但它不起作用:
ERROR: syntax error at or near "asd"
LINE 3: asd text := 'asd';
Run Code Online (Sandbox Code Playgroud)
但如果我按如下方式移动它:
CREATE OR REPLACE FUNCTION add_mail_settings_column() RETURNS void AS $$
DECLARE
asd text := 'asd';
BEGIN
END $$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
它工作正常.那么我们不能把变量声明放到函数体中吗?
我想使用带有表和几列的 plpgsql 函数作为输入参数。这个想法是将表格分成块,并对每个部分做一些事情。
我尝试了以下功能:
CREATE OR REPLACE FUNCTION my_func(Integer)
RETURNS SETOF my_part
AS $$
DECLARE
out my_part;
BEGIN
FOR i IN 0..$1 LOOP
FOR out IN
SELECT * FROM my_func2(SELECT * FROM table1 WHERE id = i)
LOOP
RETURN NEXT out;
END LOOP;
END LOOP;
RETURN;
END;
$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
my_func2() 是在每个较小的部分上做一些工作的函数。
CREATE or REPLACE FUNCTION my_func2(table1)
RETURNS SETOF my_part2 AS
$$
BEGIN
RETURN QUERY
SELECT * FROM table1;
END
$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
如果我运行:
SELECT * FROM my_func(99);
Run Code Online (Sandbox Code Playgroud)
我想我应该收到为每个 ID …
我有一个 PostgreSQL 数据库。我创建新的只读用户如下:
$ sudo -upostgres psql postgres
postgres=# CREATE ROLE readonly;
postgres=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;
postgres=# BEGIN;
postgres=# CREATE ROLE "<PUT_READONLY_USERNAME_HERE>" WITH LOGIN ENCRYPTED PASSWORD '<USE_A_NICE_STRONG_PASSWORD_PLEASE' IN ROLE readonly;
postgres=# COMMIT;
Run Code Online (Sandbox Code Playgroud)
我还有一个表“is_admin”,我在其中手动添加新用户(这种情况很少发生)。如果它是只读用户users.is_admin = false并且它是具有所有特权的用户users.is_admin = true.
users.oid users.is_admin (bool)
1 真
2 假
3 假
……
然后在代码中,我使用此查询检查用户是否为管理员:
SELECT users.is_admin
FROM users.users
JOIN pg_authid ON pg_authid.oid = users.oid::oid
WHERE rolname = "PUT_ROLNAME";
Run Code Online (Sandbox Code Playgroud)
那么,主要问题是如何自动将新用户添加到“is_admin”表中?我读过那个触发器或类似的东西可以帮助我(例如,触发器 ON CREATE ROLE)。
我有以下功能:
CREATE FUNCTION "updateStat"(_request_date timestamp without time zone, _calls integer, _latency integer) RETURNS void AS $$
BEGIN
LOCK TABLE "statistics" IN SHARE ROW EXCLUSIVE MODE;
WITH upsert AS (UPDATE "statistics" set calls = calls + _calls, total_latency = total_latency + _latency WHERE request_date=_request_date RETURNING request_date)
INSERT INTO "statistics" ("request_date", "calls", "total_latency") SELECT _request_date, _calls, _latency WHERE NOT EXISTS (SELECT "request_date" FROM upsert);
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
我怎样才能放弃这样的功能?
我尝试了以下方法:
# DROP FUNCTION updateStat(void);
ERROR: function updatestat(void) does not exist
# DROP …Run Code Online (Sandbox Code Playgroud) 我对 Postgres 非常陌生,现在我的任务是创建一个在插入后触发的触发器。基本上,我会让脚本执行插入操作,触发触发器,该触发器会根据 Insert 语句中的参数从另一个表中抓取一个字段,然后使用另一个表中的值更新新插入的记录。
INSERT INTO "TableA" VALUES ('ABC-101', 'John Doe', '')
PersonID | Name | Address
------------------------------
ABC-101 John Doe
Run Code Online (Sandbox Code Playgroud)
CREATE OR REPLACE FUNCTION fn_getaddress()
RETURNS trigger AS
$BODY$
DECLARE
PersonID TEXT;
BEGIN
PersonID := TG_ARGV[0];
UPDATE "TableA"
SET "Address" = (SELECT "Address"
FROM "TableB"
WHERE "PersonID" = PersonID);
RETURN null;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Run Code Online (Sandbox Code Playgroud)
这是我的触发器:
CREATE TRIGGER tr_getaddress
AFTER INSERT
ON TableA
FOR EACH ROW
EXECUTE PROCEDURE fn_getaddress(personid); …Run Code Online (Sandbox Code Playgroud) 我做了从oracle到pgsql的数据库迁移,并得到了如下代码:
CREATE OR REPLACE FUNCTION PKG_UTIL_BD_LOGISTICS_getsignerinfo (
i_opCode T_MQ_LOGIC_TRACK_HEAD_LOG.LP_CODE%TYPE, i_remark T_MQ_LOGIC_TRACK_HEAD_LOG.REMARK%TYPE, i_acceptTime T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNED_TIME%TYPE, i_signer T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNER%TYPE, i_lpcode T_MQ_LOGIC_TRACK_HEAD_LOG.LP_CODE%TYPE,
o_signer OUT T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNER%TYPE, o_signerTime OUT T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNED_TIME%TYPE, o_status OUT T_MQ_LOGIC_TRACK_HEAD_LOG.STATUS%TYPE )
RETURNS RECORD AS $body$
DECLARE
v_signer T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNER%TYPE;
v_signerTime T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNED_TIME%TYPE;
v_status T_MQ_LOGIC_TRACK_HEAD_LOG.STATUS%TYPE;
BEGIN
IF i_lpcode = 'SF' THEN
IF i_opCode = '8000' THEN
IF POSITION('?back' in i_remark) > 0 THEN
v_status := '3';
ELSE
v_status := '7';
v_signerTime := i_acceptTime;
v_signer := SUBSTR(i_remark, POSITION('?' in i_remark) + 1);
END IF;
ELSIF i_opCode = '9999' …Run Code Online (Sandbox Code Playgroud) plpgsql ×10
postgresql ×10
sql ×4
triggers ×3
boolean ×1
database ×1
function ×1
identifier ×1
insert ×1
row ×1
select ×1
sql-function ×1