英文:
Assign Element To Index of Array with Attribute in PostgreSSQL
问题
I have an oracle code like this:
FOR loop1 IN cursor1 LOOP
array1.EXTEND;
array1(loop1).cur_name := cursor1.name;
array1(loop1).cur_value := cursor1.value;
END LOOP;
我有一个类似这样的Oracle代码:
FOR loop1 IN cursor1 LOOP
array1.EXTEND;
array1(loop1).cur_name := cursor1.name;
array1(loop1).cur_value := cursor1.value;
END LOOP;
I tried to convert to PostgreSQL like this, but it's getting an error:
DECLARE 
  cursor1 cursor for select name, value from table;
  array1   text[];
BEGIN
  -- Do something
  ...
  FOR loop1 IN cursor1 LOOP
    array1[loop].cur_name := cursor1.name; --error here
    array1[loop1].cur_value := cursor1.value; -- error here
  END LOOP;
  -- Do something
  ...
  RETURN;
END;
我尝试将它转换成 PostgreSQL,但出现了错误:
DECLARE 
  cursor1 cursor for select name, value from table;
  array1   text[];
BEGIN
  -- Do something
  ...
  FOR loop1 IN cursor1 LOOP
    array1[loop].cur_name := cursor1.name; -- 在这里出错
    array1[loop1].cur_value := cursor1.value; -- 在这里出错
  END LOOP;
  -- Do something
  ...
  RETURN;
END;
Is there any method to create an array with an attribute name?
有没有办法创建具有属性名的数组?
英文:
Can I assign a value from cursor to index of array with attribute?
I have an oracle code like this :
cursor cursor1 is select name, value from table;
FOR loop1 IN cursor1 LOOP
array1.EXTEND;
array1(loop1).cur_name := cursor1.name;
array1(loop1).cur_value := cursor1.value;
END LOOP;
i tried to convert to postgresql like this, but it's getting error
CREATE FUNCTION function_name () RETURNS something AS $$
DECLARE 
  cursor1 cursor for select name, value from table;
  array1   text[];
BEGIN
  -- Do something
  ...
  FOR loop1 IN cursor1 LOOP
    array1[loop].cur_name := cursor1.name; --error here
    array1[loop1].cur_value := cursor1.value; -- error here
  END LOOP;
  -- Do something
  ...
  RETURN;
END;
is there any method to create an array with attibute name?
答案1
得分: 2
Oracle函数返回一个集合(如果我没记错的话,是一个“关联数组”),但已经有一段时间了。Postgres没有集合,最接近的数据类型是数组。然而,由于您的集合包含多列,您需要创建一个用户定义类型(UDT),然后您的函数返回该类型的数组。(注意:我假设了表中的数据类型。请根据需要更正。)
create type name_val as (name text, value integer);
create or replace function function_name () 
    returns name_val[]
    language plpgsql
as $$
declare 
  cursor1 cursor for
          select name, value
            from test
           limit 10;  
  rec     record;
  array1  name_val[];  
  l_name_val name_val; 
begin
  -- 做一些操作
  for rec in cursor1
  loop
    l_name_val.name = rec.name;
    l_name_val.value = rec.value; 
    array1 = array1 || l_name_val;
  end loop
  -- 做一些操作
  return array1;
end;
$$;
还有其他几种选项可以完全避免使用游标和循环。假设您确实需要返回一个数组,您可以将上述函数简化为一个单独的SQL语句:
create or replace function function_name3()
   returns name_val[]
  language sql
as $$
    select array_agg((name, value)::name_val) 
      from test 
     limit 10;
$$;
更新:<br/>
我注意到,在我回答后,您将问题从 for loop1 in 1 .. 10 ... 更改为 for rec in cursor1 ...,从而删除了结果行的限制。您只需删除Limit 10子句即可达到相同的效果。
英文:
The Oracle function is returning a collection (An Associative Array if I remember correctly, but its been awhile). Postgres does NOT have collections, the closest data type is an array. However since your collection contains multiple columns, you need to create a UDT (user defined type}, then your function returns an array of that type. (Note I  assumed the data types in the table. Correct as deeded.)
create type name_val as (name text, value integer); 
create or replace function function_name () 
    returns name_val[]
   language plpgsql
as $$
declare 
  cursor1 cursor for
          select name, value
            from test
           limit 10;  
        
  rec     record;
  array1  name_val[];  
  l_name_val name_val; 
begin
  -- do something
 
  for rec in cursor1
  loop
    l_name_val.name = rec.name;
    l_name_val.value = rec.value; 
    array1 = array1 || l_name_val;
  end loop;
  -- do something
  
  return  array1;
end;
$$;
There are a couple other option which avoid the cursor and looping altogether. Assuming you actually need any Array returned you can reduce the above function to a single sql statement:
create or replace function function_name3()
   returns name_val[]
  language sql
as $$
    select array_agg((name, value)::name_val) 
      from test 
     limit 10;
$$;
UPDATE:  <br/>
I noticed that subsequent to my answer you update the question from for loop1 in 1 .. 10 ... to for rec in cursor1 ... thus removing the resulting row limitation. You accomplish the same by just removing the Limit 10 clause.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论