标签: plpgsql

SELECT或INSERT是否容易出现竞争条件?

我写了一个函数为一个简单的博客引擎创建帖子:

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)

sql postgresql concurrency upsert plpgsql

25
推荐指数
2
解决办法
8449
查看次数

PL/pgSQL函数:如何使用execute语句返回表

我有这个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)

postgresql stored-procedures function plpgsql psql

25
推荐指数
3
解决办法
5万
查看次数

PostgreSQL:如何在没有指定参数的情况下删除函数?

我可以成功创建一个函数如下:

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)

mysql postgresql plpgsql

25
推荐指数
2
解决办法
3万
查看次数

插入访问NEW后触发Postgres

我有一个非常简单的触发器:

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)

sql postgresql triggers plpgsql

24
推荐指数
1
解决办法
4万
查看次数

它可以引用PL/pgSQL变量或表列

我在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 plpgsql pgadmin

24
推荐指数
2
解决办法
1万
查看次数

错误:必须是语言plpgsql的所有者

我使用的是PostgreSQL v9.0.1Rails(和它的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+ …

ruby postgresql activerecord ruby-on-rails plpgsql

23
推荐指数
3
解决办法
2万
查看次数

检查Postgres中是否存在序列(plpgsql)

我试图在存储过程中测试序列是否已经存在.

IF EXISTS SEQUENCE seq_name
    RAISE EXCEPTION 'sequence % already exists!', seq_name
END IF;
Run Code Online (Sandbox Code Playgroud)

我已经尝试过几个不同的片段变形而没有运气.我必须向谷歌提供错误的条款,因为我似乎无法找到关于该主题的任何内容.任何帮助表示赞赏!

postgresql stored-procedures plpgsql

23
推荐指数
4
解决办法
3万
查看次数

返回NULL的空数组的array_length()

我正在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应该在最短的时间内处理数千个电话.因此,我并不期待为处理增加不必要的开销.我只是在寻找是否有办法在循环中"循环"一个空数组.

arrays postgresql plpgsql

21
推荐指数
1
解决办法
1万
查看次数

如果不存在,如何创建序列

我试图使用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)

sql postgresql database-design plpgsql postgresql-9.2

21
推荐指数
3
解决办法
4万
查看次数

PostgreSQL - 迭代查询结果

我正在用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.如果我明白我想要做什么,你能指出我正确的方法吗?

sql postgresql plpgsql

21
推荐指数
3
解决办法
4万
查看次数