我写了一个函数为一个简单的博客引擎创建帖子:
CREATE FUNCTION CreatePost(VARCHAR, TEXT, VARCHAR[])
RETURNS INTEGER AS $$
DECLARE
InsertedPostId INTEGER;
TagName VARCHAR;
BEGIN
INSERT INTO Posts (Title, Body)
VALUES ($1, $2)
RETURNING Id INTO InsertedPostId;
FOREACH TagName IN ARRAY $3 LOOP
DECLARE
InsertedTagId INTEGER;
BEGIN
-- I am concerned about this part.
BEGIN
INSERT INTO Tags (Name)
VALUES (TagName)
RETURNING Id INTO InsertedTagId;
EXCEPTION WHEN UNIQUE_VIOLATION THEN
SELECT INTO InsertedTagId Id
FROM Tags
WHERE Name = TagName
FETCH FIRST ROW ONLY;
END;
INSERT INTO Taggings (PostId, TagId) …Run Code Online (Sandbox Code Playgroud) 我有这个PL/pgSQL函数,它必须返回一些用户信息.
CREATE OR REPLACE FUNCTION my_function(
user_id integer
) RETURNS TABLE(
id integer,
firstname character varying,
lastname character varying
) AS $$
DECLARE
ids character varying;
BEGIN
ids := '';
--Some code which build the ids string, not interesting for this issue
RETURN QUERY
EXECUTE 'SELECT
users.id,
users.firstname,
users.lastname
FROM public.users
WHERE ids IN (' || ids || ')';
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
我面临的问题是函数的结果是单列表,如下所示:
???????????????????????????
? ?my_function ?
???????????????????????????
? 1 ? (106,Ned,STARK) ?
? 2 ? (130,Rob,STARK) …Run Code Online (Sandbox Code Playgroud) 我可以成功创建一个函数如下:
CREATE FUNCTION Foo(MY_Value INT) RETURNS INT
AS 'SELECT 2 + MY_Value'
LANGUAGE SQL
Run Code Online (Sandbox Code Playgroud)
但是,如果我首先要检查函数是否存在然后删除它,那么我必须指定以下内容:
DROP FUNCTION IF EXISTS Foo(My_Value INT);
Run Code Online (Sandbox Code Playgroud)
在不指定输入参数的情况下,以下内容返回错误,指出"NOTICE:function foo()不存在,跳过"
DROP FUNCTION IF EXISTS Foo();
Run Code Online (Sandbox Code Playgroud)
与MySQL类似,有没有办法在PostgreSQL中删除FUNCTION而无需为函数指定参数?换句话说,在MySQL语句中是否存在以下等价物(即,在不指定输入参数的情况下删除存储过程)?
DROP PROCEDURE IF EXISTS Foo;
Run Code Online (Sandbox Code Playgroud) 我有一个非常简单的触发器:
CREATE OR REPLACE FUNCTION f_log_datei()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO logs (aktion, tabelle, benutzer_id) VALUES(TG_OP, 'dateien', NEW.benutzer_id);
END; $$ LANGUAGE 'plpgsql';
CREATE TRIGGER log_datei AFTER INSERT OR UPDATE OR DELETE
ON dateien
FOR EACH STATEMENT
EXECUTE PROCEDURE f_log_datei();
Run Code Online (Sandbox Code Playgroud)
我的表日志如下:
CREATE TABLE logs(
id int PRIMARY KEY DEFAULT NEXTVAL('logs_id_seq'),
zeit timestamp DEFAULT now(),
aktion char(6),
tabelle varchar(32),
alt varchar(256),
neu varchar(256),
benutzer_id int references benutzer(id)
);
Run Code Online (Sandbox Code Playgroud)
在dateien中插入内容后,我收到以下错误:
ERROR: record "new" is not assigned yet
DETAIL: The tuple structure …Run Code Online (Sandbox Code Playgroud) 我在pgsql中有一个函数
CREATE OR REPLACE FUNCTION core.date_bs_from_ad(date_in_ad date)
RETURNS character varying AS
$$
BEGIN
RETURN(
SELECT date_in_bs FROM core.date_conversion
WHERE date_in_ad = $1
);
END
$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
它创建时没有错误,但是当我使用此功能时,它会通过以下错误:
ERROR: column reference "date_in_ad" is ambiguous
LINE 3: WHERE date_in_ad = $1
^
DETAIL: It could refer to either a PL/pgSQL variable or a table column.
QUERY: SELECT (
SELECT MAX(date_in_bs) FROM core.date_conversion
WHERE date_in_ad = $1
)
CONTEXT: PL/pgSQL function core.date_bs_from_ad(date) line 3 at RETURN
********** Error **********
ERROR: column reference …Run Code Online (Sandbox Code Playgroud) 我使用的是PostgreSQL v9.0.1与Rails(和它的DEPS)@ v2.3.8,由于使用的Postgres的全文能力,我有被定义为表:
CREATE TABLE affiliate_products (
id integer NOT NULL,
name character varying(255),
model character varying(255),
description text,
price numeric(9,2),
created_at timestamp without time zone,
updated_at timestamp without time zone,
textsearch_vector tsvector,
);
注意最后一行,这确保了活动记录是无法与标准架构自卸车处理它,所以我必须设置config.active_record.schema_format = :sql在./config/environment.rb; 并使用rake db:test:clone_structure而不是rake db:test:clone.
这些都不是太了不起,只是不方便 - 但是rake db:test:clone_structure错误却失败了:
ERROR: must be owner of language plpgsql
因为#16我的结果./db/development_schema.sql:
CREATE OR REPLACE PROCEDURAL LANGUAGE plpgsql;
在超级用户安装PostgreSQL v9.0+ …
我试图在存储过程中测试序列是否已经存在.
IF EXISTS SEQUENCE seq_name
RAISE EXCEPTION 'sequence % already exists!', seq_name
END IF;
Run Code Online (Sandbox Code Playgroud)
我已经尝试过几个不同的片段变形而没有运气.我必须向谷歌提供错误的条款,因为我似乎无法找到关于该主题的任何内容.任何帮助表示赞赏!
我正在PL/pgSQL中开发一些存储过程,其中一些给我一些问题.我正在开发的sprocs通过参数接收一个数组,我在FOR LOOP中使用它来获取它的所有元素.要定义FOR LOOP的上限,我使用array_length函数.
FOR i IN 1..array_length(array,1) LOOP
--array[i] something in here
END LOOP;
Run Code Online (Sandbox Code Playgroud)
当我向sprocs提供一个空数组时会出现问题.sproc只是返回一个错误,而不是不进入循环,说明FOR LOOP的上限是NULL.不应该是0吗?
我对FOR LOOP有什么不妥吗?
有没有其他方法在LOOP中使用相同的边界而不使用空数组时返回NULL?
注意:我知道我总是可以在LOOP之前使用条件,如下所示:
IF array_length(array,1) IS NOT NULL THEN
Run Code Online (Sandbox Code Playgroud)
但问题是:这个sproc应该在最短的时间内处理数千个电话.因此,我并不期待为处理增加不必要的开销.我只是在寻找是否有办法在循环中"循环"一个空数组.
我试图使用Check中的代码来确定Postgres中是否存在序列(plpgsql).
如果序列不存在则创建序列.两次运行此代码会导致异常:
序列......已经存在.
如果序列不存在,如何创建序列?
如果序列不存在,则不应写入任何消息且不应发生错误,因此我不能在该问题的另一个答案中使用存储过程,因为如果序列存在,它每次都会将消息写入日志文件.
do $$
begin
SET search_path = '';
IF not EXISTS (SELECT * FROM pg_class
WHERE relkind = 'S'
AND oid::regclass::text = 'firma1.' || quote_ident('myseq'))
THEN
SET search_path = firma1,public;
create sequence myseq;
END IF;
SET search_path = firma1,public;
end$$;
select nextval('myseq')::int as nr;
Run Code Online (Sandbox Code Playgroud) 我正在用pgsql脚本语言创建一个函数,在这一点上我想做的是迭代查询的结果,并为每一行做一些特定的事情.我目前的尝试如下,其中temprow声明为temprow user_data.users%rowtype.有问题的代码如下:
FOR temprow IN
SELECT * FROM user_data.users ORDER BY user_seasonpts DESC LIMIT 10
LOOP
SELECT user_id,user_seasonpts INTO player_idd,season_ptss FROM temprow;
INSERT INTO user_data.leaderboards (season_num,player_id,season_pts) VALUES (old_seasonnum,player_idd,season_ptss);
END LOOP;
Run Code Online (Sandbox Code Playgroud)
但是我从这里得到以下错误:ERROR: relation "temprow" does not exist.如果我明白我想要做什么,你能指出我正确的方法吗?
plpgsql ×10
postgresql ×10
sql ×4
activerecord ×1
arrays ×1
concurrency ×1
function ×1
mysql ×1
pgadmin ×1
psql ×1
ruby ×1
triggers ×1
upsert ×1