使用Nullable参数调用PL / PGSQL函数

时间:2012-03-27 16:05:43

标签: c++ postgresql odbc plpgsql postgresql-9.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(未知,整数)不存在;

从我所看到的,调用正在尝试按顺序分配参数,忽略参数名称。

问题:

1 - 如何调用此功能才能使其正常工作?我是否必须将“NULL”作为缺失参数传递,并确保它们全部按顺序排列?

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

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

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

更新

这是DboCommand:

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

曾经是这个

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

现在,错误是:

  

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

2 个答案:

答案 0 :(得分: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驱动程序不支持它的原因。

答案 1 :(得分:1)

ERROR: function func1(unknown, integer) does not exist;

此消息表明问题:Postgres无法确定要调用哪个函数,因为它具有不完整的函数签名,没有名为func1的函数将未知类型作为其第一个arg,将整数作为第二个arg。在调用函数时尝试将占位符转换为期望的类型,以便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语句,所以我从你的绑定调用的样式,我假设命名占位符的形式:名称,使用任何正确的形式为您的odbc客户端库。我将有助于了解您正在使用的C ++客户端库。