【问题标题】:DB2 - function to return max value from specified columnDB2 - 从指定列返回最大值的函数
【发布时间】:2025-12-14 01:45:03
【问题描述】:

我是 DB2 PL/SQL 的新手,遇到了一些麻烦,因为除了官方文档并没有回答我的所有问题之外,没有太多的社区资源。

我正在做一些数据迁移,并且需要一个函数来从指定的列、指定的表中返回最大值。在过去的 2 个小时里,我提出了两种方法,但这些方法都不起作用——因为我缺乏 DB2 PL/SQL 知识。

第一个是准备查询并执行它,但我无法对变量执行选择查询。这是不执行的代码:

CREATE OR REPLACE FUNCTION getMaxColValue (schemaName VARCHAR(30), 
    tableName VARCHAR(30), columnName VARCHAR(30))
-- function used to get max ID of a column during data migration
RETURNS INTEGER
LANGUAGE SQL
BEGIN
    DECLARE query VARCHAR(1000);
    DECLARE maxColValue INT;
    DECLARE stmt STATEMENT;

  SET query = 'select max(' || columnName || ') from ' || schemaName || '.' || tableName || '';
    PREPARE stmt FROM query;
    EXECUTE query INTO maxColValue;
    RETURN maxColValue;

END

返回错误:

Lookup Error - DB2 Database Error: ERROR [07003] [IBM][DB2/AIX64] SQL0518N  The statement named in the EXECUTE statement is not in a prepared state or is a SELECT or VALUES statement.

我也尝试过类似的方法,返回标量 SQL 值:

CREATE FUNCTION getMaxColValue_2 (schemaName VARCHAR(30), tableName VARCHAR(30), columnName VARCHAR(30))
     RETURNS INT 
     LANGUAGE SQL
     READS SQL DATA
     NO EXTERNAL ACTION
     DETERMINISTIC
     RETURN
       SELECT max(columnName)
         FROM schemaName.tableName;

返回错误:

Lookup Error - DB2 Database Error: ERROR [42704] [IBM][DB2/AIX64] SQL0204N  "SCHEMANAME.TABLENAME" is an undefined name.

但我想在这里传递模式名和表名作为变量更难。我会竭诚为您提供帮助。窗口函数不是一个很好的选择,因为我需要在迁移过程中使用这个函数而不是简单的选择语句。

有一些语法错误,但更糟糕的是,由于我缺乏 PL/SQL 知识,可能存在一些逻辑错误。

干杯, 乔尼

【问题讨论】:

  • 请用您收到的错误编辑您的问题。例如,它可能只是权限错误。
  • 完成了,但我猜之后还会有更多错误,因为我还没有完全掌握函数类型和逻辑。
  • @Gordon_Linoff 将 'BEGIN ATOMIC' 替换为 'BEGIN' 后,函数执行,但是当我尝试运行时:select ub.getMaxColValue('pk', 'pk_reguly', 'reg_id') from sysibm.sysdummy1 我得到:查找错误 - DB2 数据库错误:错误 [07003] [IBM ][DB2/AIX64] SQL0518N EXECUTE 语句中指定的语句未处于准备状态,或者是 SELECT 或 VALUES 语句。我已经编辑了原始帖子,所以第一个函数现在可以执行了。

标签: sql db2


【解决方案1】:

你不能在EXECUTE SELECT 声明,这正是错误消息告诉你的内容。

相反,您应该声明一个游标,打开它,然后将结果提取到您的变量中:

CREATE OR REPLACE FUNCTION getMaxColValue (schemaName VARCHAR(30), 
tableName VARCHAR(30), columnName VARCHAR(30))
RETURNS INTEGER
LANGUAGE SQL
not deterministic
reads sql data
begin
 declare l_max int;
 declare c_cur cursor for l_stmt;

 prepare l_stmt from 'select max(' || columnName || ') from ' || rtrim(schemaName) ||
 '.' || tableName;
 open c_cur;
 fetch c_cur into l_max;
 close c_cur;
 return l_max;
end

【讨论】:

  • 非常感谢伙计,这正是我所需要的。我之前尝试过一些带有光标的 shananigans,但没有做到那么远:)