Informix 12.1 如何根据 case 子句中的条件选择条件
Informix 12.1 How to choose a condition, based on condition in case clause
|在这样的过程中进行查询:
{
table1
column1 column2 column3 column4
a a x 1
b b y 4
c c y 4
d c y 4
}
CREATE PROCEDURE PROCEDURE1(input1 smallint)
insert into table1
select
column1,column2,column3,column4
From
Table1
WHERE
column1 not in ('a','b')
AND
CASE
WHEN input1=1 THEN "column2 in ('a' ,'b')" --lead to syntax error and with quote, i.e. : "column2 in (a ,b)" lead to boolean expression error
WHEN input1=2 THEN "column3 in ('x' ,'y')"
ELSE "column4 not in ('1' ,'2')"
END;
END PROCEDURE;
如果在 Case 子句中使用引号输入条件字符串,我会收到此错误:
"Result of a boolean expression is not of boolean type"
如果我从 in Case 子句中的条件字符串中删除引号,我会收到语法错误。
有人可以帮忙吗?
(使用PREPARE语句有this problem)
我认为您要执行的操作可能需要:
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND ((input1 = 1 AND column2 IN ('a', 'b')) OR
(input1 = 2 AND column3 IN ('x', 'y')) OR
(input1 != 1 AND input1 != 2 AND column4 NOT IN ('1', '2'))
)
请注意,我已将 INSERT 的目标 table 更改为 Table2
;没有充分的理由将行插入您要从中选择数据的 table — 数据已经存在,重复的行只会增加混乱。但是,如果你坚持目标 table 应该与源 table 相同并且没有主键来阻止你滥用它,那么你可以使用 INSERT INTO Table1 SELECT … FROM Table1 …
,对我来说有点惊喜(Informix 12.10.FC6 测试)。
您可以将其重写为:
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND ((input1 IN (1) AND column2 IN ('a', 'b')) OR
(input1 IN (2) AND column3 IN ('x', 'y')) OR
(input1 NOT IN (1, 2) AND column4 NOT IN ('1', '2'))
)
这强调了 OR 项的主要组成部分的异同。
由此生成 MCVE (Minimal, Complete, Verifiable Example — or MRE or whatever name SO now uses) or an SSCCE (Short, Self-Contained, Correct Example):
DROP TABLE IF EXISTS Table1;
DROP TABLE IF EXISTS Table2;
DROP PROCEDURE IF EXISTS procedure1;
CREATE TEMP TABLE Table1
(
column1 CHAR(1) NOT NULL,
column2 CHAR(1) NOT NULL,
column3 CHAR(1) NOT NULL,
column4 CHAR(1) NOT NULL
);
INSERT INTO Table1 VALUES('a', 'a', 'x', '1');
INSERT INTO Table1 VALUES('b', 'b', 'y', '4');
INSERT INTO Table1 VALUES('c', 'c', 'y', '4');
INSERT INTO Table1 VALUES('d', 'c', 'y', '4');
CREATE TEMP TABLE Table2
(
column1 CHAR(1) NOT NULL,
column2 CHAR(1) NOT NULL,
column3 CHAR(1) NOT NULL,
column4 CHAR(1) NOT NULL
);
CREATE PROCEDURE procedure1(input1 SMALLINT)
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND ((input1 = 1 AND column2 IN ('a', 'b')) OR
(input1 = 2 AND column3 IN ('x', 'y')) OR
(input1 != 1 AND input1 != 2 AND column4 NOT IN ('1', '2'))
);
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND ((input1 IN (1) AND column2 IN ('a', 'b')) OR
(input1 IN (2) AND column3 IN ('x', 'y')) OR
(input1 NOT IN (1, 2) AND column4 NOT IN ('1', '2'))
);
END PROCEDURE;
EXECUTE PROCEDURE procedure1(1);
SELECT * FROM Table2;
DELETE FROM Table2;
EXECUTE PROCEDURE procedure1(2);
SELECT * FROM Table2;
DELETE FROM Table2;
EXECUTE PROCEDURE procedure1(3);
SELECT * FROM Table2;
使用我的 SQLCMD 程序(与 Microsoft 的同名 johnny-come-lately 程序无关,并且比它更早),我得到:
+ DROP TABLE IF EXISTS Table1;
+ DROP TABLE IF EXISTS Table2;
+ DROP PROCEDURE IF EXISTS procedure1;
+ CREATE TEMP TABLE Table1
(
column1 CHAR(1) NOT NULL,
column2 CHAR(1) NOT NULL,
column3 CHAR(1) NOT NULL,
column4 CHAR(1) NOT NULL
);
+ INSERT INTO Table1 VALUES('a', 'a', 'x', '1');
+ INSERT INTO Table1 VALUES('b', 'b', 'y', '4');
+ INSERT INTO Table1 VALUES('c', 'c', 'y', '4');
+ INSERT INTO Table1 VALUES('d', 'c', 'y', '4');
+ CREATE TEMP TABLE Table2
(
column1 CHAR(1) NOT NULL,
column2 CHAR(1) NOT NULL,
column3 CHAR(1) NOT NULL,
column4 CHAR(1) NOT NULL
);
+ CREATE PROCEDURE procedure1(input1 SMALLINT)
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a','b')
AND ((input1 = 1 AND column2 IN ('a' ,'b')) OR
(input1 = 2 AND column3 IN ('x' ,'y')) OR
(input1 != 1 AND input1 != 2 AND column4 NOT IN ('1' ,'2'))
);
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a','b')
AND ((input1 IN (1) AND column2 IN ('a' ,'b')) OR
(input1 IN (2) AND column3 IN ('x' ,'y')) OR
(input1 NOT IN (1, 2) AND column4 NOT IN ('1' ,'2'))
);
END PROCEDURE;
+ EXECUTE PROCEDURE procedure1(1);
+ SELECT * FROM Table2;
+ DELETE FROM Table2;
+ EXECUTE PROCEDURE procedure1(2);
+ SELECT * FROM Table2;
c|c|y|4
d|c|y|4
c|c|y|4
d|c|y|4
+ DELETE FROM Table2;
+ EXECUTE PROCEDURE procedure1(3);
+ SELECT * FROM Table2;
c|c|y|4
d|c|y|4
c|c|y|4
d|c|y|4
由于有两个 INSERT 语句,预计 Table2 将包含插入的每一行的两个副本。当然,table 应该有一个主键,以防止这种关系理论的滥用。
您还应该考虑是否最好单独编写 3 个操作而不在查询中提及 input1
:
CREATE PROCEDURE procedure2(input1 SMALLINT)
IF input1 = 1 THEN
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND column2 IN ('a', 'b');
ELIF input1 = 2 THEN
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND column3 IN ('x', 'y');
ELSE
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND column4 NOT IN ('1', '2');
END IF;
END PROCEDURE;
如果您的查询非常大,您也可以考虑使用视图甚至 CTE(常见 table 表达式)功能。
|在这样的过程中进行查询:
{
table1
column1 column2 column3 column4
a a x 1
b b y 4
c c y 4
d c y 4
}
CREATE PROCEDURE PROCEDURE1(input1 smallint)
insert into table1
select
column1,column2,column3,column4
From
Table1
WHERE
column1 not in ('a','b')
AND
CASE
WHEN input1=1 THEN "column2 in ('a' ,'b')" --lead to syntax error and with quote, i.e. : "column2 in (a ,b)" lead to boolean expression error
WHEN input1=2 THEN "column3 in ('x' ,'y')"
ELSE "column4 not in ('1' ,'2')"
END;
END PROCEDURE;
如果在 Case 子句中使用引号输入条件字符串,我会收到此错误:
"Result of a boolean expression is not of boolean type"
如果我从 in Case 子句中的条件字符串中删除引号,我会收到语法错误。
有人可以帮忙吗?
(使用PREPARE语句有this problem)
我认为您要执行的操作可能需要:
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND ((input1 = 1 AND column2 IN ('a', 'b')) OR
(input1 = 2 AND column3 IN ('x', 'y')) OR
(input1 != 1 AND input1 != 2 AND column4 NOT IN ('1', '2'))
)
请注意,我已将 INSERT 的目标 table 更改为 Table2
;没有充分的理由将行插入您要从中选择数据的 table — 数据已经存在,重复的行只会增加混乱。但是,如果你坚持目标 table 应该与源 table 相同并且没有主键来阻止你滥用它,那么你可以使用 INSERT INTO Table1 SELECT … FROM Table1 …
,对我来说有点惊喜(Informix 12.10.FC6 测试)。
您可以将其重写为:
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND ((input1 IN (1) AND column2 IN ('a', 'b')) OR
(input1 IN (2) AND column3 IN ('x', 'y')) OR
(input1 NOT IN (1, 2) AND column4 NOT IN ('1', '2'))
)
这强调了 OR 项的主要组成部分的异同。
由此生成 MCVE (Minimal, Complete, Verifiable Example — or MRE or whatever name SO now uses) or an SSCCE (Short, Self-Contained, Correct Example):
DROP TABLE IF EXISTS Table1;
DROP TABLE IF EXISTS Table2;
DROP PROCEDURE IF EXISTS procedure1;
CREATE TEMP TABLE Table1
(
column1 CHAR(1) NOT NULL,
column2 CHAR(1) NOT NULL,
column3 CHAR(1) NOT NULL,
column4 CHAR(1) NOT NULL
);
INSERT INTO Table1 VALUES('a', 'a', 'x', '1');
INSERT INTO Table1 VALUES('b', 'b', 'y', '4');
INSERT INTO Table1 VALUES('c', 'c', 'y', '4');
INSERT INTO Table1 VALUES('d', 'c', 'y', '4');
CREATE TEMP TABLE Table2
(
column1 CHAR(1) NOT NULL,
column2 CHAR(1) NOT NULL,
column3 CHAR(1) NOT NULL,
column4 CHAR(1) NOT NULL
);
CREATE PROCEDURE procedure1(input1 SMALLINT)
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND ((input1 = 1 AND column2 IN ('a', 'b')) OR
(input1 = 2 AND column3 IN ('x', 'y')) OR
(input1 != 1 AND input1 != 2 AND column4 NOT IN ('1', '2'))
);
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND ((input1 IN (1) AND column2 IN ('a', 'b')) OR
(input1 IN (2) AND column3 IN ('x', 'y')) OR
(input1 NOT IN (1, 2) AND column4 NOT IN ('1', '2'))
);
END PROCEDURE;
EXECUTE PROCEDURE procedure1(1);
SELECT * FROM Table2;
DELETE FROM Table2;
EXECUTE PROCEDURE procedure1(2);
SELECT * FROM Table2;
DELETE FROM Table2;
EXECUTE PROCEDURE procedure1(3);
SELECT * FROM Table2;
使用我的 SQLCMD 程序(与 Microsoft 的同名 johnny-come-lately 程序无关,并且比它更早),我得到:
+ DROP TABLE IF EXISTS Table1;
+ DROP TABLE IF EXISTS Table2;
+ DROP PROCEDURE IF EXISTS procedure1;
+ CREATE TEMP TABLE Table1
(
column1 CHAR(1) NOT NULL,
column2 CHAR(1) NOT NULL,
column3 CHAR(1) NOT NULL,
column4 CHAR(1) NOT NULL
);
+ INSERT INTO Table1 VALUES('a', 'a', 'x', '1');
+ INSERT INTO Table1 VALUES('b', 'b', 'y', '4');
+ INSERT INTO Table1 VALUES('c', 'c', 'y', '4');
+ INSERT INTO Table1 VALUES('d', 'c', 'y', '4');
+ CREATE TEMP TABLE Table2
(
column1 CHAR(1) NOT NULL,
column2 CHAR(1) NOT NULL,
column3 CHAR(1) NOT NULL,
column4 CHAR(1) NOT NULL
);
+ CREATE PROCEDURE procedure1(input1 SMALLINT)
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a','b')
AND ((input1 = 1 AND column2 IN ('a' ,'b')) OR
(input1 = 2 AND column3 IN ('x' ,'y')) OR
(input1 != 1 AND input1 != 2 AND column4 NOT IN ('1' ,'2'))
);
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a','b')
AND ((input1 IN (1) AND column2 IN ('a' ,'b')) OR
(input1 IN (2) AND column3 IN ('x' ,'y')) OR
(input1 NOT IN (1, 2) AND column4 NOT IN ('1' ,'2'))
);
END PROCEDURE;
+ EXECUTE PROCEDURE procedure1(1);
+ SELECT * FROM Table2;
+ DELETE FROM Table2;
+ EXECUTE PROCEDURE procedure1(2);
+ SELECT * FROM Table2;
c|c|y|4
d|c|y|4
c|c|y|4
d|c|y|4
+ DELETE FROM Table2;
+ EXECUTE PROCEDURE procedure1(3);
+ SELECT * FROM Table2;
c|c|y|4
d|c|y|4
c|c|y|4
d|c|y|4
由于有两个 INSERT 语句,预计 Table2 将包含插入的每一行的两个副本。当然,table 应该有一个主键,以防止这种关系理论的滥用。
您还应该考虑是否最好单独编写 3 个操作而不在查询中提及 input1
:
CREATE PROCEDURE procedure2(input1 SMALLINT)
IF input1 = 1 THEN
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND column2 IN ('a', 'b');
ELIF input1 = 2 THEN
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND column3 IN ('x', 'y');
ELSE
INSERT INTO Table2
SELECT column1, column2, column3, column4
FROM Table1
WHERE column1 NOT IN ('a', 'b')
AND column4 NOT IN ('1', '2');
END IF;
END PROCEDURE;
如果您的查询非常大,您也可以考虑使用视图甚至 CTE(常见 table 表达式)功能。