1

问题:

我在使用 plpgsql 语言在 Postgres (9.1) 中创建的函数时遇到问题。我来自 SQL Server 的世界,所以这里有一点语言差距。

我的问题是 postgres 似乎没有分配我正确传递的参数。

这是我的函数定义:

CREATE OR REPLACE FUNCTION func1 (
    IN param1 character varying,
    IN param2 character varying DEFAULT NULL::character varying,
    IN param3 int DEFAULT NULL::int)
RETURNS void
AS $$
BEGIN
    INSERT INTO table1
    (
        col1
        , col2
        , col3
    )
    VALUES
    (
        $1
        , $2
        , $3
    )
END;
$$ LANGUAGE plpgsql;

该函数本身在数据库环境中测试时工作正常,但我目前正试图通过 ODBC 连接从 C++ 调用它。

这里是我设置参数的地方:

pCmd->paramIn( "param1", (char *)name.getString().c_str() );
pCmd->paramIn( "param3", 100 );

在这种情况下,我没有将 param2 分配给任何值。它是可空的 - 不应该是一个问题。

我得到的错误是:

错误:函数 func1(unknown, integer) 不存在;

从我所见,调用试图按顺序分配参数,忽略参数名称。

问题:

1 - 我怎样才能调用这个函数来完成这项工作?我是否必须将“NULL”作为缺少的参数传递,并确保它们都井然有序?

2 - 如果我使用的是 ODBC 连接,我肯定是,我应该调用一个 SQL 语言函数,而该函数又调用一个 PLPGSQL 函数吗?这有点令人费解,但我愿意尝试。

3 - (不是问题)请不要建议“不要使用 ODBC”。另外,除非必要,否则请不要尝试更改函数的内部结构。我现在主要关心的是学习如何通过 ODBC 在 postgres 中进行函数调用。

提前感谢大家花时间阅读本文,并非常感谢任何回答的人。

更新:

这是 DboCommand:

DboCommand *cmd;
cmd = new DboCommand(dbConnection, "{call func1 (?) (?)}");

曾经是这个

cmd = new DboCommand(dbConnection, "func1");

现在,错误是:

绑定参数的数量 < 参数标记的数量

4

2 回答 2

2

问题 #1:是的,您必须传递 NULL 并关心订单(和类型)。

理论上,可以使用命名或位置表示法的参数调用 PostgreSQL 函数。它在这里解释:http ://www.postgresql.org/docs/9.1/static/sql-syntax-calling-funcs.html

仅使用位置表示法时,只有在省略任何后续参数的情况下,才可以省略第 N 个参数。由于您的 ODBC 驱动程序清楚地使用此表示法,因此如果要指定第 3 个参数,则必须指定第 2 个参数。据推测,您在客户端代码中为参数选择的名称与 plpgsql 函数声明的名称完全无关,位置和参数类型对于匹配对现有函数的调用很重要。

问题 #2:引入 SQL 存根函数对此无济于事。

问题 #3:从调用者的角度命名参数的可能性是最近的(我认为出现在 PG 9.0 中),所以这可能是 ODBC 驱动程序不支持它的原因。

于 2012-03-27T18:09:15.970 回答
1
ERROR: function func1(unknown, integer) does not exist;

此消息表明了问题:Postgres 无法确定要调用的函数,因为它的函数签名不完整,没有名为 func1 的函数将未知类型作为其第一个参数,将整数作为第二个参数。在调用函数时尝试将占位符转换为预期的类型,以便 postgres 可以解析签名,例如:func1(:param1::character varying, :param2::character varying, :param3::integer)func1( CAST(:param1 as character varying), CAST(:param2 as character varying), CAST(:param3 as integer) ). 您没有发布函数调用或 sql 语句,所以我根据您的绑定调用的样式,假设命名占位符的形式为:name,使用您的 odbc 客户端库的正确形式。了解您正在使用的 C++ 客户端库对我很有帮助。

于 2012-03-27T17:35:40.977 回答