bash - 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
不幸的是,从数组中读取的术语,即 ${} 没有在过程内部解释
我还尝试通过创建两个过程并调用其中一个并争论条件来解决问题,但条件不是布尔形式而是字符串形式,就像在过程中定义数组一样。
有人可以帮忙吗?
解决方案
在每个 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。语法中可能存在我没有发现的问题,但我希望这个想法应该足够清楚。一个关键点是巨大的表达式每个只写一次——这很重要。
推荐阅读
- mongodb - 我可以将 3.6 次要添加到 2.6 MongoDB 副本集吗
- java - 如何为 Webflux 应用程序包装阻塞 IO 操作
- angular - 在Angular 6中重置反应表单时输入不会禁用
- asp.net-core - 我无法在 .net core 3.1 Web 应用程序中将现有项目(.net core worker service app)添加为 azure webjob
- c++ - 通过迭代器修改不反映
- android - 如何限制用户仅从 Cloud Firestore 检索他们的数据?
- python - 转义空格的问题?系统找不到路径
- databricks - 以编程方式设置集群、池和作业访问控制
- pdf - 在创建pdf时正确使用pylatex中的append和Alignat(python)
- sql - 添加外键时奇怪的mysql行为