我有18对不同的表列名称,如:
name_1, surname_1, ... name_18, surname_18
我想用以下内容生成18个Informix SPL插件:
define _counter Int;
define _name_1 varchar(20);
define _surname_1 varchar(20);
...
define _name_18 varchar(20);
define _surname varchar(20);
select name_1, surname_1, ..., name_18, surname_18
into _name_1, _surname_1, ..., _name_18, _surname_18
from names where name_id = 1;
for _counter = 1 to 18 loop
insert into person(name, surname) values (_name_+_counter, _surname_+_counter);
end loop
如果我试试这个,我会收到语法错误。我被困在可怕的桌子设计中。你能否告诉我们是否有类似/正确的方法来完成这项工作?
答案 0 :(得分:1)
鉴于问题的轮廓更清晰,我认为你必须放弃循环。您可以做的最好的是18个连续的INSERT语句,或18个对每次调用执行一个语句的存储过程的调用。
Informix SPL没有数组类型,您只能将循环与数组一起使用。 (我已经看到内部带有CASE语句的循环,循环的每次迭代都有一个案例;它们很少能很好地解决问题,而且对于这种情况来说这不是一个明智的解决方案。)
我将重复我先前评论中的一个观察结果:具有18对柱的表的设计非常不理想。但是,您似乎正在尝试将数据从此次优模式传输到更合理的模式,每个名称只有一行。
您还可以考虑使用18路UNION:
INSERT INTO Person(Name, Surname)
SELECT Name_1, Surname_1 FROM Names -- WHERE name_id = 1
UNION
SELECT Name_2, Surname_2 FROM Names -- …
UNION …
SELECT Name_18, Surname_18 FROM Names -- …
如果要求确实只有name_id = 1
行,则需要将该标准添加到UNION SELECT语句中的18个SELECT子句中的每一个。还有其他方法可以添加该过滤条件,在源代码级别使用不同的权衡集(并且可能在优化器中进行不同的权衡)。 Informix(尚未)支持CTE(公用表表达式,又名WITH子句),这在这种情况下很可惜。
请注意,显示的代码在一个SQL语句中将所有数据从Names传输到Person。这可能是最接近最佳整体流程的。
答案 1 :(得分:0)
也许这样的东西就是你想要的(使用informix 12.10FC6,不确定它是否适用于以前的版本):
CREATE PROCEDURE copy_paste_names (p_name_id INTEGER);
DEFINE
l_query_string VARCHAR(255);
DEFINE
iter INT;
FOR iter IN (1 TO 18 STEP 1)
LET l_query_string = 'INSERT INTO person (name, surname) SELECT name_' || iter || ', surname_' || iter || ' FROM names WHERE name_id = ' || p_name_id || ';';
EXECUTE IMMEDIATE l_query_string;
END FOR;
END PROCEDURE;
我假设names
表总是有18对名为name_?
和surname_?
的列。
此过程只是盲目地尝试将name_?
表中的每对surname_?
,names
列复制到person
表中的新行。没有任何类型的检查来查看是否实际存在要复制的值或是否