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

时间:2012-05-30 23:00:40

标签: sql informix

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

这是一个经常出现的问题,但我看到了关于informix的noyhing。

我找到了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来创建和执行该过程。 Run Windows 7 Ultimate 32-Bits

提前致谢。任何帮助

2 个答案:

答案 0 :(得分:4)

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

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

感谢您提出问题。你说:

EXECUTE PROCEDURE test_hector('{stspols,stsrepo}');
     

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

这可能是一个比表面上看起来更简单的问题。过程的输入类型应该是一个集合 - 实际上是SET值的LIST - 其中每个值都是一个字符串。您可以将其写为:

EXECUTE PROCEDURE test_hector(LIST{SET{'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 {}注释,但无法识别集合异常。在这种情况下,您可能会收到语法错误(因为如果您将第一个}解释为开始注释符号,则不会出现第二个{。在这种情况下,请使用以下符号之一。

收集符号(SET,MULTISET,LIST)随着时间的推移逐渐发展。这种替代符号也有效(并且与您最初尝试的内容关系更密切,并且是最初记录的内容):

EXECUTE PROCEDURE test_hector('LIST{SET{''stspols'',''stsrepo''}}');

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

EXECUTE PROCEDURE test_hector('LIST{SET{"stspols","stsrepo"}}');
EXECUTE PROCEDURE test_hector("LIST{SET{'stspols','stsrepo'}}");

从下面的讨论中,如替代答案中所述,现在问题似乎与嵌套集合有关。 LIST{SET{"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更改为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

答案 1 :(得分:0)

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

我修改了程序以接受List的参数,而不是List{SET...

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"}');

它就像一个魅力。