标签: plpgsql

使用 plpgsql 进行递归查询

我正在尝试编写一个plpgsql函数,该函数从树结构中的记录递归返回一组列。

我有一个数据表和一个将数据链接在一起的表:

DATATABLE
-----------
id integer
value text
info text

LINKTABLE
-----------
link integer
parent integer
Run Code Online (Sandbox Code Playgroud)

我的想法是在以下功能中做类似的事情:

CREATE OR REPLACE FUNCTION my_function(itemID integer)
  RETURNS TABLE(id integer, value text) AS
$BODY$
BEGIN    
    RETURN QUERY SELECT my_function(A.link) FROM linktable A, datatable B 
        WHERE A.parent = B.id AND B.id = itemID) C;

    RETURN QUERY SELECT id, value FROM datatable WHERE id = itemID;            
    RETURN;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
Run Code Online (Sandbox Code Playgroud)

但这不起作用,我在第一个查询中遇到错误:

错误:查询结构与函数结果类型不匹配

我的Just-In-Brain编译器没有检测到任何问题,那么我在这里做错了什么?

postgresql plpgsql functions postgresql-9.2

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

在 PostgreSQL 中使用动态列名

我正在使用 PostgreSSQL 8.3。

我想执行这个查询:

select COALESCE(col_fr,col,'Unknown') from my_table where id = 'abc';
Run Code Online (Sandbox Code Playgroud)

故事中的扭曲是列名colum_fr应该动态生成。my_table对于不同的语言有不同的列。就像是:

id   col   col_ja    col_fr
Run Code Online (Sandbox Code Playgroud)

我在水晶报告中使用此查询,我可以在其中传递语言的字符串参数:

select COALESCE(col_||{?parameter},col,'Unknown') from my_table where id = 'abc';
Run Code Online (Sandbox Code Playgroud)

如果{?language}value 是,它将在内部转换为如下内容fr

select COALESCE(col_||'fr',col,'Unknown') from my_table where id = 'abc';
Run Code Online (Sandbox Code Playgroud)

这永远不会奏效。

我不想使用选择大小写,使其动态化。
作为替代解决方案,我还尝试创建一个存储过程:

CREATE OR REPLACE FUNCTION get_policy_name (
  id text,
  lang   text,
  def_value text
)
RETURNS SETOF record AS
$body$
DECLARE
   sql text;
BEGIN
    sql := 'SELECT   COALESCE(col_'||quote_ident(lang)||',col,'||quote_literal(def_value)||')FROM my_table WHERE id ='||quote_literal(id);

   RETURN QUERY EXECUTE …
Run Code Online (Sandbox Code Playgroud)

postgresql stored-procedures dynamic-sql plpgsql postgresql-8.3

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

如何在函数中按顺序对表列表运行 ALTER TABLE

我有一个模式(称为import),其中数据作为表导入,以及一个处理它们的函数。之后我想将这些表移到另一个模式中(称为data_archive)中。现有功能运行良好,但我找不到更改架构的方法;这是我编写的一个函数:

我的想法是根据selecta 为该管理制作的表格提供的标准创建表格列表,然后遍历此列表并执行以下操作Alter table xxxx SET schema data_archive

CREATE OR REPLACE FUNCTION archive_datasets()
  RETURNS VOID AS
$BODY$
DECLARE
   table_rec  record;

BEGIN

   FOR table_rec IN
      SELECT t.table_name
      FROM information_schema.tables AS t
      WHERE table_schema = 'import'
      AND quote_ident(t.table_name) IN (
              SELECT "table_name"
              FROM data_sets 
              WHERE status IN ('Processed', 'Archived', 'Deleted')
              ) 

   LOOP
     ALTER TABLE quote_ident(table_rec.table_name) SET schema data_archived;
   END LOOP;

END;
$BODY$
  LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

但我收到此错误消息:

ERROR:  syntax error at or near "("
LINE 28: …
Run Code Online (Sandbox Code Playgroud)

postgresql dynamic-sql alter-table plpgsql functions

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

如何使用表列中的值作为 SELECT 查询中的字段名称?

设想:

Table1 的字段名称命名为 testtable

ID、名称、大小、宽度、高度

Table2 的字段名称命名为 errortable

id,desc,field1,field2,operator

errortable 的值

+----+-------------------------------------+--------+--------+----------+
| id |                desc                 | field1 | field2 | operator |
+----+-------------------------------------+--------+--------+----------+
|  1 | size should not greater than width  | size   | width  | >        |
|  2 | size should not greater than height | size   | height | >        |
|  3 | with should be equal to height      | width  | height | <>       |
+----+-------------------------------------+--------+--------+----------+
Run Code Online (Sandbox Code Playgroud)

现在我想检查testtable

  1. 计算大小 > 宽度的所有记录。
  2. 计算大小 …

mysql postgresql dynamic-sql plpgsql

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

将 SQL SERVER 过程转换为 POSTGRESQL

我在 SQL Server 中有程序可以打印给定国家/地区的所有玩家。我尝试将其转换为 plpgsql,但出现错误。

SQL Server 过程

CREATE PROCEDURE kraj_pilkarze @kraj varchar(30)
AS
DECLARE @idkraj INT
DECLARE @nazwa_zespolu varchar(30)
SELECT @idkraj = id_kraj FROM kraj WHERE @kraj=nazwa
DECLARE kursor_pilk CURSOR
FOR SELECT imie,nazwisko, id_zespol, id_kraj FROM pilkarz
DECLARE @imie varchar(20), @nazwisko varchar(30), @zespol int, @d_kraj int
OPEN kursor_pilk
FETCH NEXT FROM kursor_pilk INTO @imie, @nazwisko,@zespol, @d_kraj
WHILE @@FETCH_STATUS=0
    BEGIN
    IF @d_kraj=@idkraj
        BEGIN
            SELECT @nazwa_zespolu = nazwa FROM zespol WHERE @zespol=id_zespol 
            PRINT @imie+' '+@nazwisko+', '+@nazwa_zespolu
            FETCH NEXT FROM kursor_pilk INTO …
Run Code Online (Sandbox Code Playgroud)

postgresql sql-server cursors plpgsql functions

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

使用 RETURNING 子句直接从 INSERT 返回值

我有一个以以下结尾的函数:

    INSERT INTO configuration_dates (
      cols...
    ) VALUES (
      values...
    ) RETURNING id INTO ret_id;
    RETURN ret_id;
Run Code Online (Sandbox Code Playgroud)

我想删除该INTO ret_id部分,而是执行以下操作:

RETURN (INSERT INTO configuration_dates (
  weekly_date_configuration_id,
  "from",
  "to",
  price,
  activity_configuration_id
) VALUES (
  wdc_id,
  from_ts,
  from_ts + wdc.duration,
  wdc.price,
  wdc.activity_configuration_id
) RETURNING id);
Run Code Online (Sandbox Code Playgroud)

但我还没有找到如何实现这一点。

编辑:添加整个功能

CREATE FUNCTION make_date_from_configuration(wdc_id UUID, from_date DATE)
  RETURNS INTEGER AS $$
DECLARE
  from_dow INT := EXTRACT(isodow FROM from_date); -- day of the week (1 - 7)
  wdc weekly_date_configurations;
  from_ts TIMESTAMP;
  ret_id INTEGER;
BEGIN
  SELECT * …
Run Code Online (Sandbox Code Playgroud)

postgresql parameter plpgsql functions

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

创建一个临时表,循环,添加数据,从中选择?“查询没有结果数据的目的地”

我正在创建一个临时表,并从多个表中获取数据并将数据插入其中。当我尝试从表中取回数据时,出现错误:

[42601] ERROR: query has no destination for result data
Hint: If you want to discard the results of a SELECT, use PERFORM instead.
Run Code Online (Sandbox Code Playgroud)
do
$$
    DECLARE
        sampleproductId   varchar;
        productIds        text[] := array [
            'abc1',
            'abc2'
            ];
        tId              varchar;
        DECLARE result  jsonb;
        DECLARE resultS jsonb[];
    begin
       CREATE TEMP TABLE IF NOT EXISTS product_temp_mapping
        (
            accountid      int,
            productUID      varchar,
            sampleproductId text
        );
        FOREACH sampleproductId IN ARRAY productIds
            LOOP
                tId := (select id
                        from product.product
                        where uid = sampleproductId);
                INSERT into product_temp_mapping …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql

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

如何定义一个只接受三个字符的函数?

我试过这个:

create or replace function c3 (arg char(3))
  returns void
  language plpgsql as
$$
begin
  raise notice 'Value: %', arg;
end;
$$;
Run Code Online (Sandbox Code Playgroud)

但它接受三个以上的字符:

select c3('1234');
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql functions

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

Postgresql - 返回表的函数出错

我刚刚定义了这个函数来返回给定表中的所有列名:

create or replace function GET_COLUMNS(in tbl_name character varying(30))
returns table(colunas character varying) as $$
begin
    SELECT column_name
    FROM information_schema.columns
    WHERE table_schema = 'Main'
    AND table_name   = tbl_name;
end;
$$ language 'plpgsql'
Run Code Online (Sandbox Code Playgroud)

但是当我使用它调用它时,select * from get_columns('tabfuncionarios');我收到了以下错误:

ERROR:  query has no destination for result data
HINT:  If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT:  PL/pgSQL function get_columns(character varying) line 3 at SQL statement
Run Code Online (Sandbox Code Playgroud)

我正在使用postgresql 9.4.5版本

postgresql plpgsql

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

选择与另一个日期范围有 50% 重叠的日期范围

我有一系列包含列的日期范围,例如 start_date、end_date、period_name

   1         100     Roman
 -50          75     Iron Age b
-100          20     Iron Age a
Run Code Online (Sandbox Code Playgroud)

我的团队要求我构建 2 个查询:

  1. 选择罗马时期和任何重叠的时期

  2. 与 1 相同,但仅限重叠 >40% 的范围

我假设我必须在 postgresql (PL/pgSQL) 中编写一个函数,非常欢迎任何帮助。

postgresql plpgsql

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