Informix:如何将单个参数中的多个值传递、使用和执行到存储过程

Posted

技术标签:

【中文标题】Informix:如何将单个参数中的多个值传递、使用和执行到存储过程【英文标题】:Informix: How to pass, use and execute multiple values in a single parameter to a stored procedure 【发布时间】:2012-05-30 23:00:40 【问题描述】:

如何将单个参数中的多个值传递给 Informix 中的存储过程?。

这是一个常见的问题,但我没有看到关于 informix 的任何信息。

我找到了post,但它对我不起作用,应该是数据库的版本还是我遗漏了什么?

我正在尝试执行WHERE X IN (SELECT Y FROM TABLE(PARAM))

编辑:

这是我尝试做的一个例子。

CREATE PROCEDURE test_hector
(
    C LIST( SET (CHAR(10) NOT NULL ) NOT NULL)
)
RETURNING CHAR(10) AS C, CHAR(10) AS CVE, CHAR(50) AS DESC;

DEFINE vColumna like tclaves.columna;
DEFINE vClave like tclaves.clave;
DEFINE vdescve like tclaves.descve;

FOREACH
select columna, clave, descve
INTO vColumna, vClave,vdescve
from tclaves
where columna in (SELECT * FROM TABLE(C))
RETURN vColumna, vClave,vdescve WITH RESUME;
END FOREACH
END PROCEDURE;

我正在尝试执行它,但我认为我遇到了 sintax 问题

EXECUTE PROCEDURE test_hector( 'stspols,stsrepo');

我收到错误消息[Informix][Informix ODBC Driver][Informix]Invalid collection literal value.

我执行了这个函数execute function se_release()来获取informix版本,这就是我得到的。

column1
Spatial DataBlade Release 8.21.FC4R1 (Build 238)                 Compiled on Thu Aug 26 19:42:55 CDT 2010 with:                      IBM Informix Dynamic Server Version 10.00.FC7                    glslib-4.00.UC10

我正在使用Aqua Data Studio 8.0.22 来创建和执行该过程。在Windows 7 Ultimate 32-Bits上运行

提前致谢。任何帮助

【问题讨论】:

相同的解决方案***.com/questions/11038298/… 【参考方案1】:

将参数类型定义为适当的集合类型:LIST、SET、MULTISET(这是我在交叉引用问题的答案中所说的)。

什么不适合你? 您尝试了什么? 您收到的错误消息是什么? 您使用的是哪个版本的 Informix 服务器? 您使用哪个工具或 API 创建存储过程? 您使用哪个工具或 API 来执行存储过程? 您在哪个平台上运行? 您如何调用该过程?

感谢您详细说明问题。你说:

EXECUTE PROCEDURE test_hector('stspols,stsrepo');

我收到错误消息[Informix][Informix ODBC Driver][Informix]Invalid collection literal value.

这可能比表面上看起来更容易解决。该过程的输入类型应该是一个集合——实际上是一个 SET 值的列表——其中每个值都是一个字符串。你可以这样写:

EXECUTE PROCEDURE test_hector(LISTSET'stspols','stsrepo');

我自己创建了一个虚拟程序来测试这个语法:

CREATE PROCEDURE test_hector(c LIST(SET (CHAR(10) NOT NULL ) NOT NULL))
    RETURNING CHAR(10) AS C, CHAR(10) AS CVE, CHAR(50) AS DESC;
    return "abc", "def", "ghi";
END PROCEDURE;

它的输出和预期的一样:

abc   def   ghi

请注意,Informix 支持以 开头并以 结尾的注释样式。但是,当 之前的关键字是 SET、MULTISET 或 LIST 之一时,该注释样式会被抑制(是的,这确实使它很难解析!)。您可以通过“在上面的 SQL 中在哪里添加 ”来获得巨大(如果变态)的乐趣,而不会改变其含义。 API 有可能识别 Informix cmets 但无法识别集合异常。在这种情况下,您可能会得到一个语法错误(因为如果您将第一个 解释为开始注释符号,则不需要第二个 )。在这种情况下,请使用以下符号之一。

集合(SET、MULTISET、LIST)文字的表示法随着时间的推移而演变。这种替代符号也有效(并且与您最初尝试的内容更密切相关,并且是最初记录的内容):

EXECUTE PROCEDURE test_hector('LISTSET''stspols'',''stsrepo''');

SET 中的字符串必须用引号括起来,但整个文字本身就是一个字符串,因此您需要将嵌入的引号加倍。您也可以“作弊”并使用双引号和单引号:

EXECUTE PROCEDURE test_hector('LISTSET"stspols","stsrepo"');
EXECUTE PROCEDURE test_hector("LISTSET'stspols','stsrepo'");

从下面的讨论以及替代答案中所述,问题现在似乎与嵌套集合有关。 LISTSET"str1", "str2" 是一个有序列表(其中有一个条目);该条目本身就是一组(不同的)字符串,没有特定的顺序。如果您需要能够重复字符串(但顺序并不重要),您将使用 MULTISET。使用 LIST 很重要,顺序很重要(列表中允许重复)。

听起来你真的只需要选择参数类型,这样它就更简单了。您应该能够有效地使用任何一种集合类型;我可能会提名 SET 以便您不必处理列表中的重复字符串,但 MULTISET 或 LIST 也是有效的选项。将程序重命名为test_3()

CREATE PROCEDURE test_3(c SET(CHAR(10) NOT NULL))
    RETURNING CHAR(10) AS r;
    DEFINE r CHAR(10);
    FOREACH SELECT * INTO r FROM TABLE(c)
        RETURN r WITH RESUME;
    END FOREACH;
END PROCEDURE;

我能够执行以下两个语句,并显示结果:

+ EXECUTE PROCEDURE test_3(SET'stspols','stsrepo');
stspols
stsrepo
+ EXECUTE PROCEDURE test_3('SET''stspols'',''stsrepo''');
stspols
stsrepo

这是使用 ESQL/C 接口。您应该能够获得第二个使用 ODBC;第一个可能会导致 -201 语法错误。

如果您更喜欢 LIST 而不是 SET,则在上面的代码中将 SET 更改为 LIST:

+ CREATE PROCEDURE test_3(c LIST(CHAR(10) NOT NULL))
    RETURNING CHAR(10) AS r;
    DEFINE r CHAR(10);
    FOREACH SELECT * INTO r FROM TABLE(c)
        RETURN r WITH RESUME;
    END FOREACH;
END PROCEDURE;
+ EXECUTE PROCEDURE test_3(LIST'stspols','stsrepo');
stspols
stsrepo
+ EXECUTE PROCEDURE test_3('LIST''stspols'',''stsrepo''');
stspols
stsrepo

【讨论】:

我编辑了我的问题来回答你的问题。提前感谢您的帮助! 这样写 EXECUTE PROCEDURE test_hector(LISTSET'stspols','stsrepo'); 抛出 [Informix][Informix ODBC Driver][Informix]A syntax error has occurred. 。像这样写EXECUTE PROCEDURE test_hector('LISTSET''stspols'',''stsrepo'''); throws ` [Informix][Informix ODBC Driver][Informix]尚未实现。 sqlerrm(=any, !=any, =all, or !=all for Collections) ` 'EXECUTE PROCEDURE test_hector('LISTSET"stspols","stsrepo"');'抛出[Informix][Informix ODBC Driver][Informix]Not implemented yet. sqlerrm(=any, !=any, =all, or !=all for Collections) :( +1 顺便说一句以获得完整的解释。几乎可以工作,我认为我们缺少一些东西 我怀疑第一次失败是由于 ODBC 驱动程序错误解析 SQL 并试图将 视为注释的开始。第二次失败看起来语法通过了,但是处理它时出了点问题。在这个阶段,我不确定这是 ODBC 问题还是服务器问题。我怀疑我需要为您的存储过程升级我的代理,以便它尝试从字符串集列表中访问数据,看看会发生什么。你试过我的超简单程序吗?它是否引发错误? 你的工作就像一个魅力!,也许问题出在where columna in (SELECT * FROM TABLE(C)),再次感谢您的宝贵帮助!【参考方案2】:

我以不同的方式尝试了它并找到了解决方案。

我修改了过程以接受一个参数,就像List,而不是ListSET...

CREATE PROCEDURE test_hector
(
    C LIST( CHAR(10) NOT NULL )
)
RETURNING CHAR(10) AS C, CHAR(10) AS CVE, CHAR(50) AS DESC;

DEFINE vColumna like tclaves.columna;
DEFINE vClave like tclaves.clave;
DEFINE vdescve like tclaves.descve;

FOREACH
select columna, clave, descve
INTO vColumna, vClave,vdescve
from tclaves
where columna in (SELECT * FROM TABLE(C))
RETURN vColumna, vClave,vdescve WITH RESUME;
END FOREACH
END PROCEDURE;

并像这样执行它。

EXECUTE PROCEDURE test_hector('LIST''stspols'',''stsrepo''');

或者这样

EXECUTE PROCEDURE test_hector3('LIST"stspols","stsrepo"');

它就像一个魅力。

【讨论】:

以上是关于Informix:如何将单个参数中的多个值传递、使用和执行到存储过程的主要内容,如果未能解决你的问题,请参考以下文章

在 Reporting Services 中为单个参数传递多个值

如何在erl中为单个标志设置多个命令行参数

使用ado.net将多个SQL表值参数传递到单个存储过程

如何将多个值附加到 html 表单中的单个参数?

如何将多个参数作为单个向量传递给函数?

在单个参数中传递多个值