You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何遍历Redshift表获取行数?存储过程执行报错求助

问题描述

需要遍历指定schema下的表以获取各表行数,尝试使用CTE语句时因无法混合不同节点失败:

WITH tables_i_want AS (
    SELECT *, table_schema||'.'||table_name as tbl FROM temp.redshift_mod_dates WHERE table_schema = 'whatever'
)
SELECT nspname
FROM pg_catalog.pg_class AS c
JOIN pg_catalog.pg_namespace AS ns
  ON c.relnamespace = ns.oid
INNER JOIN tables_i_want as tiw
    ON tiw.tbl = c.oid
AND relname not like 'pg_%'

随后尝试编写存储过程,但执行时出现语法错误:

CREATE OR REPLACE PROCEDURE f_test()
LANGUAGE plpgsql
AS $$
DECLARE
  full_table_name1 VARCHAR;
    full_table_name VARCHAR;
BEGIN
  FOR full_table_name IN (SELECT table_schema||'.'||table_name as full_table_name FROM temp.redshift_mod_dates WHERE table_schema = 'whatever')
  LOOP
      EXECUTE 'SELECT INTO temp.redshift_tables_with_cnt %, COUNT(*) FROM %', full_table_name;
      RAISE INFO '%', full_table_name;
  END LOOP;
END;
$$;

错误信息:

[42601] ERROR: syntax error at or near "$1" Where: SQL statement in PL/PgSQL function "f_test" near line 5

寻求正确实现遍历表获取行数的方法及存储过程报错的解决办法。


一、存储过程报错修复方案

上述存储过程存在两个核心问题:

  1. 动态SQL参数替换逻辑错误:PL/pgSQL中EXECUTE不支持%作为占位符,且表名属于标识符,直接拼接会引发语法错误或SQL注入风险,需用format()函数安全处理。
  2. 数据插入语法错误:SELECT INTO用于创建新表并插入数据,若目标表已存在,应使用INSERT INTO ... SELECT ...语法。

修复后的存储过程:

CREATE OR REPLACE PROCEDURE f_test()
LANGUAGE plpgsql
AS $$
DECLARE
  full_table_name VARCHAR;
BEGIN
  -- 可选:清空目标表,避免重复数据
  TRUNCATE TABLE temp.redshift_tables_with_cnt;
  
  FOR full_table_name IN (
    SELECT table_schema||'.'||table_name 
    FROM temp.redshift_mod_dates 
    WHERE table_schema = 'whatever'
  )
  LOOP
      -- 用format函数安全拼接SQL:%L处理字符串字面量,%I处理标识符
      EXECUTE format(
        'INSERT INTO temp.redshift_tables_with_cnt (table_name, row_count) SELECT %L, COUNT(*) FROM %I',
        full_table_name,
        full_table_name
      );
      RAISE INFO '已处理表: %', full_table_name;
  END LOOP;
END;
$$;

前置要求:确保目标表已创建,结构如下:

CREATE TABLE temp.redshift_tables_with_cnt (table_name VARCHAR(256), row_count BIGINT);

二、高效获取表行数的替代方案(无需遍历查询)

Redshift提供系统视图直接维护表行数统计,比逐表执行COUNT(*)效率高数十倍,优先推荐以下两种方式:

方法1:使用svv_table_info(最准确)

该视图由Redshift自动更新,行数统计精度高:

SELECT 
  schemaname||'.'||tablename AS full_table_name,
  rows AS row_count
FROM svv_table_info
WHERE schemaname = 'whatever'
AND tablename IN (
  SELECT table_name 
  FROM temp.redshift_mod_dates 
  WHERE table_schema = 'whatever'
);

方法2:使用pg_class系统表(统计信息有延迟)

依赖PostgreSQL原生统计字段,适合对实时性要求不高的场景:

SELECT
  ns.nspname||'.'||c.relname AS full_table_name,
  c.reltuples::BIGINT AS row_count
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace ns ON c.relnamespace = ns.oid
WHERE ns.nspname = 'whatever'
AND c.relname IN (
  SELECT table_name 
  FROM temp.redshift_mod_dates 
  WHERE table_schema = 'whatever'
)
AND c.relkind = 'r'; -- 仅筛选普通用户表

内容的提问来源于stack exchange,提问作者jayykaa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:00:59