首页 > 解决方案 > informix 12.10 在一个过程中,在循环中对条件进行多个查询

问题描述

我有这样的程序:

CREATE PROCEDURE   PROCEDURE1 (var1 type1)
INSERT INTO TEMP
select * from table1 where Huge_Expression1 AND  condition1 
select * from table1 where Huge_Expression1 AND  condition2  
select * from table1 where Huge_Expression1 AND  condition3
.. 
select * from table1 where Huge_Expression2 AND  condition1 
select * from table1 where Huge_Expression2 AND  condition2  
select * from table1 where Huge_Expression2 AND  condition3
..
select * from table1 where Huge_Expression3 AND  condition1 
select * from table1 where Huge_Expression3 AND  condition2  
select * from table1 where Huge_Expression3 AND  condition3
END   PROCEDURE

问题是该过程非常庞大且难以调试。

我的努力如下:

#!/bin/bash
# file name is script1

condH[1]="Huge_Expression1"
condH[2]="Huge_Expression2"
condH[3]="Huge_Expression3"

Run_Proc() {
    dbaccess $dbname << EOF

   CREATE PROCEDURE   PROCEDURE (var1 type1)

   INSERT INTO TEMP

   FOR i = 1 TO 3
    select * from table1 where ${condH[i]} AND  condition1
    select * from table1 where ${condH[i]} AND  condition2
    select * from table1 where ${condH[i]} AND  condition3
    ..
   END fOR

   END PROCEDURE
   --
  execute procedure PROCEDURE1(var1)
   EOF
   }

   Run_Proc $dbname
   #
   #Which is executed in the shell in this way
   ./script1 database1

不幸的是,从数组中读取的术语,即 ${} 没有在过程内部解释

我还尝试通过创建两个过程并调用其中一个并争论条件来解决问题,但条件不是布尔形式而是字符串形式,就像在过程中定义数组一样。

有人可以帮忙吗?

标签: bashstored-proceduresinformix

解决方案


在每个 SELECT 语句之前是否有 INSERT INTO TEMP,或者在 SELECT 语句之间使用 UNION,还是什么?在某种程度上,答案是什么并不重要。

您可以很容易地组合前三个查询:

INSERT INTO temp_table
    SELECT *
      FROM table1
     WHERE (Huge_Expression1) AND ((condition1) OR (condition2) OR (condition3))

您可以使用以下符号组合所有三个序列:

INSERT INTO temp_table
    SELECT *
      FROM table1
     WHERE ((Huge_Expression1) AND ((condition1) OR (condition2) OR (condition3))
        OR ((Huge_Expression2) AND ((condition1) OR (condition2) OR (condition3))
        OR ((Huge_Expression3) AND ((condition1) OR (condition2) OR (condition3))

您也许可以将其减少到:

INSERT INTO temp_table
    SELECT *
      FROM table1
     WHERE ((Huge_Expression1) OR (Huge_Expression2) OR (Huge_Expression3))
       AND ((condition1) OR (condition2) OR (condition3))

您可能需要担心重复的行。

如果巨大的条件是稳定的,你也许可以使用视图:

CREATE VIEW table1_hc1
    AS (SELECT *
          FROM table1
         WHERE Huge_Expression1
       );

然后,您可以将查询的第一个三元组编写为:

INSERT INTO temp_table
    SELECT *
      FROM table1_hc1
     WHERE ((condition1) OR (condition2) OR (condition3))

你可以用其他两个“巨大的条件”做同样的工作。

或者,如果您使用 Informix 14.10 或更高版本,您可以使用 CTE(公用表表达式):

WITH
   table1_hc1 AS (SELECT * FROM table1 WHERE (Huge_Expression1)),
   table1_hc2 AS (SELECT * FROM table1 WHERE (Huge_Expression2)),
   table3_hc3 AS (SELECT * FROM table1 WHERE (Huge_Expression3))
SELECT *
  FROM table1_hc1 WHERE ((condition1) OR (condition2) OR (condition3))
 UNION
SELECT *
  FROM table1_hc2 WHERE ((condition1) OR (condition2) OR (condition3))
 UNION
SELECT *
  FROM table1_hc3 WHERE ((condition1) OR (condition2) OR (condition3))

或者作为:

WITH
   table1_hc1 AS (SELECT * FROM table1 WHERE (Huge_Expression1)),
   table1_hc2 AS (SELECT * FROM table1 WHERE (Huge_Expression2)),
   table3_hc3 AS (SELECT * FROM table1 WHERE (Huge_Expression3))
SELECT *
  FROM (SELECT * FROM table1_hc1
         UNION
        SELECT * FROM table1_hc2
         UNION
        SELECT * FROM table1_hc3
       )
 WHERE ((condition1) OR (condition2) OR (condition3))

如果这三个巨大的表达式有很多共同点,可能还有其他方法可以重写它。

我观察到您的大纲代码没有显示在查询中如何使用过程参数。这可能会影响使用的查询。特别是,您不能将变量嵌入到视图定义中。它不需要显着影响其他重写。

以防万一,建议的 SQL 都没有靠近 DBMS。语法中可能存在我没有发现的问题,但我希望这个想法应该足够清楚。一个关键点是巨大的表达式每个只写一次——这很重要。


推荐阅读