如何在多个插入语句中生成变量名?

How to generate variable names in multiple insert statement?

我有 18 对不同的 table 列名称,例如:

name_1, surname_1, ... name_18, surname_18

我想使用 Informix SPL 生成 18 个插入:

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 

如果我尝试这样做,我会收到语法错误。我坚持可怕的 table 设计。您能告诉我是否有一些 similar/correct 方法可以完成这个吗?

也许你想要这样的东西(使用 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 table 将始终有 18 对列,分别命名为 name_?surname_?

此过程将只是盲目地尝试将 names table 中的每一对 name_?surname_? 列复制到 [=17= 中的新行中] table。没有任何类型的检查来查看是否确实有要复制的值或者是否

鉴于问题的轮廓更清晰,我认为你必须放弃循环。您可以做的最好的事情是 18 个连续的 INSERT 语句,或者 18 次调用存储过程,每次调用都执行一个语句。

Informix SPL 没有数组类型,您只能真正使用带有数组的循环。 (我见过内部有 CASE 语句的循环,循环的每次迭代一个案例;它们很少是解决问题的好方法,而且对于这种情况也不是明智的解决方案。)

我将重复我之前评论中的一个观察:具有 18 对列的 table 的设计非常次优。但是,您似乎正在尝试将数据从这个次优模式传输到一个更合理的模式,每个名称一行。

您也可以考虑使用 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(常见的 table 表达式,又名 WITH 子句),在这种情况下很遗憾。

请注意,显示的代码在单个 SQL 语句中将所有数据从 Names 传输到 Person。这很可能是最接近整体最佳流程的。