我必须编写一个存储过程,它将接受以逗号分隔的电影ID字符串,并将从dB中获取电影名称列表。我试过,但我不确定语法是否正确,显然db Vis正在抛出语法错误
Pl.Help。
Code:
CREATE PROCEDURE test_sp() returning VARCHAR(255);
begin
define set_movieIds, t_movieNames varchar(255);
define t_movieID varchar(5);
define t_count, t_length integer;
let set_movieIds = '54565' ||',' || '55258' || ',' || '55711' || ',' ||'52719' || ',';
let t_length = length(set_movieIds);
for t_count IN (0 TO t_length) loop
IF(set_movieIds[t_count] is not ',')
THEN
for t_count in (t_count to t_count+4)
let t_movieID[t_count] = set_movieIds[t_count]
end for;
select movie_name into t_movieNames
from tbl_cinemasource_movieinfo
where movie_id = t_movieID
let t_movieNames = t_movieNames || ',';
end if;
exit when t_count = t_length;
end loop;
return t_movieNames;
end;
END PROCEDURE;
答案 0 :(得分:4)
这里有各种各样的问题。
CREATE PROCEDURE test_sp() returning VARCHAR(255);
begin
这个BEGIN
并没有具体错误,但它是一种常规且不必要的。
define set_movieIds, t_movieNames varchar(255);
define t_movieID varchar(5);
define t_count, t_length integer;
let set_movieIds = '54565' ||',' || '55258' || ',' || '55711' || ',' ||'52719' || ',';
为什么不只是一个简单的文字?为什么一个尾随的逗号?然而,这些都是化妆品,而非功能性问题。
let t_length = length(set_movieIds);
for t_count IN (0 TO t_length) loop
这不是Informix SPL(存储过程语言)中支持的表示法。你会写一个更传统的循环:
FOR t_count = 0 TO t_length
...继续
IF (set_movieIds[t_count] is not ',') THEN
IS NOT
几乎必须遵循NULL
(尽管标准SQL也允许TRUE
,FALSE
或UNKNOWN
。但无论如何,你正在寻找一个'不等于'的运营商。括号是可选的。
IF set_movieIds[t_count] != ',' THEN
补充:SPL不太令人满意的功能之一是使用下标符号编写的字符串下标只能使用常量整数作为下标。幸运的是,有一种解决问题的方法,使用SUBSTR()函数代替:
IF SUBSTR(set_movieIds, t_count, 1) != ',' THEN
...继续
for t_count in (t_count to t_count+4)
从句法上讲,应该是:
FOR t_count = t_count TO t_count+4
从语义上讲,这让我很头疼。这个内循环需要一个额外的变量;
FOR u_count = t_count TO t_count+4
...继续
let t_movieID[t_count] = set_movieIds[t_count]
end for;
我不清楚你要复制什么。我想你可能需要一个从1开始的变量(我称之为v_count
)和u_count
然后:
LET t_movieID[v_count] = set_movieIds[u_count];
LET v_count = v_count + 1;
[这也需要调整。]
在LET之后没有分号你可能没问题,你可能没有。那里的不一致让我感到疯狂。
...继续
select movie_name into t_movieNames
from tbl_cinemasource_movieinfo
where movie_id = t_movieID
在SELECT语句之后你需要一个分号。
let t_movieNames = t_movieNames || ',';
end if;
exit when t_count = t_length;
此表示法不是SPL的一部分。你必须写:
IF t_count = LENGTH THEN EXIT FOR; END IF;
(你可能不需要这两个分号。)OTOH,你也将进入FOR循环的下一个循环。上面引入u_count
后,您可能需要调整t_count
。
end loop;
您必须编写END FOR以结束FOR循环;你写END IF结束IF声明;您编写END XYZ以结束XYZ构造。这至少是一致的。
return t_movieNames;
end;
END PROCEDURE;
解剖那里的东西太多了。话虽如此,感觉真的很不舒服。我通常希望写一个粗略的程序,将每个电影标题作为单独的结果返回。我还希望使用除字符串之外的其他内容来描述要选择的电影。由于列表在此处是硬编码的,因此我将修改SELECT语句以使用IN列表。如果列表是可变的,我会使用一个临时表填充我所追求的电影ID。这将在此程序之外创建。或者,假设您使用的是当前(支持)版本的Informix Dynamic Server(而不是IDS 7.x或OnLine 5.20),那么您可以使用一组整数(或VARCHAR(5))值来描述列表电影。
因此,在最简单的情况下,我会:
CREATE PROCEDURE test_sp() RETURNING VARCHAR(255) AS movieName;
DEFINE t_movieNames varchar(255);
FOREACH SELECT movie_name
INTO t_movieNames
FROM tbl_cinemasource_movieinfo
WHERE movie_id IN (54565, 55258, 55711, 52719)
RETURN t_movieNames WITH RESUME;
END FOREACH;
END PROCEDURE;