0

我有一个要求,我需要将 RedshiftInformation schema表与User defined表连接起来。我尝试了以下查询并得到了提到的错误。

select *
from pg_table_def a join user_defined_table b
on 1 = 1 -- condition just to give an example
where tablename = 'table1'; 

SQL Error [500310] [0A000]: [Amazon](500310) Invalid operation: Specified types or functions (one per INFO message) not supported on Redshift tables.;

select *
from information_schema.columns  a join user_defined_table b
on 1 =1 -- condition just to give an example
where a.table_name = 'table1';

SQL Error [500310] [0A000]: [Amazon](500310) Invalid operation: Specified types or functions (one per INFO message) not supported on Redshift tables.;

可能是我缺少一些基础知识,请建议。

4

1 回答 1

2

当您发现位于领导节点上的目录表与普通表完全不同时。将这些表中的数据与普通表一起使用的方法是将这些目录表中的数据保存为普通表。然后可以在您尝试时组合数据。

如果不从目录中选择(据我所知),没有从这些表直接到普通表的路径。因此,您可以从 redshift 中选择这些数据,然后使用脚本或程序将其作为普通表放回。或者,您可以通过选择光标并将光标读入普通表格来执行几乎等效的操作。这种从游标读取的操作可以通过存储过程来完成。我们先来看看这条路。

下面的代码创建了一个存储过程,生成普通表“fred”,选择 pg_table_def 数据并将其放入 fred,然后执行存储过程,最后选择存储在 fred 中的内容。

CREATE OR REPLACE procedure rewrite_data()
AS
$$
DECLARE 
  row record;
BEGIN
  drop table if exists fred;
  create table fred (schemaname varchar(256),tablename varchar(256),"column"varchar(256), "type"varchar(256));
  for row in select "schemaname"::text, "tablename"::text, "column"::text, "type"::text from pg_table_def where "schemaname" <> 'pg_catalog' LOOP
    INSERT INTO fred(schemaname,tablename,"column","type") VALUES (row.schemaname,row.tablename,row."column",row."type");
  END LOOP;
END;
$$ LANGUAGE plpgsql;
call rewrite_data();
select * from fred;

此过程运行良好,但一次循环遍历游标一行很慢,在我们进行时将一行插入到 fred 上。这个过程适用于小事情,但有些目录表相当大。这个过程的好处在于,fred 的更新可以在需要时作为 SQL 调用来完成。这个过程非常适合需要由其他 SQL 启动的小更新。

在很多行上循环的速度是游标/存储过程方法的坏处。在 1000 行游标上循环 10 秒。因此,如果您需要将大量仅限领导节点的目录数据复制到普通表中,您将需要看起来更像 ETL 过程的东西。读取目录表,将其写入 S3,然后将其复制到您的表中。这很容易做到,而且速度相当快,但不能由 SQL 命令启动,因此这些表在使用时会过期一段时间(这些表在上次更新时是正确的)。

因此,没有完美的解决方案,只有几个可行的解决方案,具体取决于您的需求。

于 2020-12-30T00:24:23.267 回答