UPDATE 命令出现语法错误
A syntax error has occurred on UPDATE command
这是 Informix 更新的正确语法吗?
UPDATE da1010
SET d1.da1_prcven = s9.b9_cm1, d1.datvig = s9.b9_data
FROM da1010 d1
INNER JOIN sb1010 s1
ON (d1.da1_codpro = s1.b1_cod AND s1.d_e_l_e_t_ <> '*')
INNER JOIN sb9010 S9
ON (s9.b9_filial = '0101' AND s9.b9_cm1 <> 0 AND d1.da1_codpro = s9.b9_cod AND d1.da1_datvig < s9.b9_data AND s1.b1_locpad = s9.b9_local AND s9.d_e_l_e_t_ <> '*')
WHERE d1.da1_codtab = '009'
AND d1.d_e_l_e_t_ <> '*'
AND s9.b9_data = (SELECT MAX(b9_data) FROM SB9010)
当我向编辑器发出执行查询的命令时 returns 出现语法错误(-201:发生语法错误)。
我看到你用请求的信息更新 table da1010,但在那一行:
SET d1.da1_prcven = s9.b9_cm1, d1.datvig = s9.b9_data
你更新 table D1 的信息而不是 table da1010 的信息吗?正确的更新如下:
UPDATE da1010
SET da1010.da1_prcven = s9.b9_cm1, da1010.datvig = s9.b9_data
FROM da1010 d1
INNER JOIN sb1010 s1
ON (d1.da1_codpro = s1.b1_cod AND s1.d_e_l_e_t_ <> '*')
INNER JOIN sb9010 S9
ON (s9.b9_filial = '0101' AND s9.b9_cm1 <> 0 AND d1.da1_codpro = s9.b9_cod AND d1.da1_datvig < s9.b9_data AND s1.b1_locpad = s9.b9_local AND s9.d_e_l_e_t_ <> '*')
WHERE d1.da1_codtab = '009'
AND d1.d_e_l_e_t_ <> '*'
AND s9.b9_data = (SELECT MAX(b9_data) FROM SB9010)
PS: 不能在update中使用别名,只能在FROM之后使用。
您将需要使用语法符合 Informix 支持的 UPDATE 语句。
一般形式为:
UPDATE target
SET (col1, …, colN) = ((SELECT val1, …, valN FROM WhereEver …))
WHERE …
SET 子句右侧的双括号是有意且必要的。主 UPDATE 中的 WHERE 子句必须确保只选择将使用 SELECT 语句中的值更新的行。如果不这样做,没有匹配条目的行将 col1, …, colN
设置为 NULL,这很少是我们想要的。
尝试将此应用到您的查询中,可能与此类似:
UPDATE da1010 AS d1
SET (da1_prcven, datvig) = ((SELECT s9.b9_cm1, s9.b9_data
FROM sb1010 s1
JOIN sb9010 S9 ON (s9.b9_filial = '0101' AND
s9.b9_cm1 <> 0 AND
s9.b9_cod = s1.b1_cod AND
s9.b9_local = s1.b1_locpad AND
s9.d_e_l_e_t_ <> '*')
WHERE d1.da1_codtab = '009'
AND d1.da1_datvig < s9.b9_data
AND d1.da1_codpro = s1.b1_cod
AND d1.d_e_l_e_t_ <> '*'
AND s1.d_e_l_e_t_ <> '*'
AND s9.b9_data = (SELECT MAX(b9_data) FROM sb9010)
))
WHERE d1.da1_codtab = '009'
AND d1.d_e_l_e_t_ <> '*';
这不正确,但足以纠正它运行并更新目标 table、d1010
。
用于测试的示例 SQL。请注意,问题中的 SQL 指的是 da1010
table 中的 datvig
和 da1_datvig
。我认为 datvig
可能是一个错字,但由于未提供大纲架构,因此很难确定。
CREATE TABLE da1010
(
da1_prcven INTEGER,
datvig INTEGER, -- Original references both datvig and da1_datvig
da1_datvig INTEGER, -- Original references both datvig and da1_datvig
da1_codpro INTEGER,
da1_codtab CHAR(3),
d_e_l_e_t_ CHAR(1)
);
CREATE TABLE sb1010
(
b1_cod INTEGER,
b1_locpad INTEGER,
d_e_l_e_t_ CHAR(1)
);
CREATE TABLE sb9010
(
b9_cm1 INTEGER,
b9_data INTEGER,
b9_cod INTEGER,
b9_local INTEGER,
b9_filial CHAR(4),
d_e_l_e_t_ CHAR(1)
);
INSERT INTO da1010 VALUES(100, 1000, 100, 100, '009', 'N');
INSERT INTO da1010 VALUES(102, 1000, 101, 102, '009', 'N');
INSERT INTO da1010 VALUES(102, 1000, 101, 102, '009', '*');
INSERT INTO sb1010 VALUES(100, 20, 'N');
INSERT INTO sb1010 VALUES(100, 30, '*');
INSERT INTO sb1010 VALUES(101, 99, 'N');
INSERT INTO sb1010 VALUES(102, 40, 'N');
INSERT INTO sb1010 VALUES(102, 50, '*');
INSERT INTO sb9010 VALUES(2345, 3456, 100, 20, '0101', 'N');
INSERT INTO sb9010 VALUES(2344, 3466, 102, 40, '0101', 'N');
INSERT INTO sb9010 VALUES(2343, 3476, 100, 20, '0101', 'N');
INSERT INTO sb9010 VALUES(2342, 3486, 100, 20, '0101', 'N');
INSERT INTO sb9010 VALUES(2341, 3496, 101, 40, '0101', 'N');
INSERT INTO sb9010 VALUES(2345, 3456, 100, 20, '0101', '*');
INSERT INTO sb9010 VALUES(2344, 3466, 102, 40, '0101', '*');
INSERT INTO sb9010 VALUES(2343, 3476, 100, 20, '0101', '*');
INSERT INTO sb9010 VALUES(2342, 3486, 100, 20, '0101', '*');
INSERT INTO sb9010 VALUES(2341, 3496, 101, 40, '0101', '*');
之前:
SELECT * FROM da1010;
100|1000|100|100|009|N
102|1000|101|102|009|N
102|1000|101|102|009|*
之后:
SELECT * FROM da1010;
||100|100|009|N
||101|102|009|N
102|1000|101|102|009|*
如您所见,两行中的 da1_prcven
和 datvig
列已被取消。这表明了一些事情:
- 我没有生成满足更新条件的数据。
- 我没有充分选择主 UPDATE 中的 WHERE 子句。它很可能需要来自主 WHERE 子句中 SET 子句的 SELECT 语句的重要部分。
但是,我无法确切地了解 UPDATE 应该做什么,所以我不愿意花更多的时间来猜测接下来会发生什么。
另一种选择是使用 MERGE:
MERGE INTO dept d
USING dept_online o
ON (d.deptno = o.deptno)
WHEN MATCHED THEN
UPDATE SET d.dname = o.dname, d.loc = o.loc;
经过大量的query和attentation研究informix的文档后,我得出了问题的解决方案,我在这里与大家分享以完成主题。
CREATE PROCEDURE proc_update_table()
DEFINE x_cod varchar(15) ; --declaration local variable
DEFINE x_date varchar(8) ;
DEFINE x_vlr float ;
FOREACH --selects rows according to query
SELECT b9_cod, b9_data, b9_cm1
INTO x_cod, x_date, x_vlr
FROM SB9010
INNER JOIN DA1010 ON (b9_cod = da1_codpro AND da1_datvig < b9_data)
INNER JOIN SB1010 ON (b9_cod = b1_cod AND b9_local = b1_locpad)
WHERE b9_cm1 <> '0'
AND SB9010.d_e_l_e_t_ <> '*'
AND b9_data = (SELECT MAX(b9_data) FROM SB9010)
UPDATE DA1010 --update fields with variables values
SET da1_prcven = x_vlr, da1_datvig = x_date
AND da1_codpro = x_cod
AND da1_datvig < x_date
AND d_e_l_e_t_ <> '*';
END FOREACH;
END PROCEDURE;
这是 Informix 更新的正确语法吗?
UPDATE da1010
SET d1.da1_prcven = s9.b9_cm1, d1.datvig = s9.b9_data
FROM da1010 d1
INNER JOIN sb1010 s1
ON (d1.da1_codpro = s1.b1_cod AND s1.d_e_l_e_t_ <> '*')
INNER JOIN sb9010 S9
ON (s9.b9_filial = '0101' AND s9.b9_cm1 <> 0 AND d1.da1_codpro = s9.b9_cod AND d1.da1_datvig < s9.b9_data AND s1.b1_locpad = s9.b9_local AND s9.d_e_l_e_t_ <> '*')
WHERE d1.da1_codtab = '009'
AND d1.d_e_l_e_t_ <> '*'
AND s9.b9_data = (SELECT MAX(b9_data) FROM SB9010)
当我向编辑器发出执行查询的命令时 returns 出现语法错误(-201:发生语法错误)。
我看到你用请求的信息更新 table da1010,但在那一行:
SET d1.da1_prcven = s9.b9_cm1, d1.datvig = s9.b9_data
你更新 table D1 的信息而不是 table da1010 的信息吗?正确的更新如下:
UPDATE da1010
SET da1010.da1_prcven = s9.b9_cm1, da1010.datvig = s9.b9_data
FROM da1010 d1
INNER JOIN sb1010 s1
ON (d1.da1_codpro = s1.b1_cod AND s1.d_e_l_e_t_ <> '*')
INNER JOIN sb9010 S9
ON (s9.b9_filial = '0101' AND s9.b9_cm1 <> 0 AND d1.da1_codpro = s9.b9_cod AND d1.da1_datvig < s9.b9_data AND s1.b1_locpad = s9.b9_local AND s9.d_e_l_e_t_ <> '*')
WHERE d1.da1_codtab = '009'
AND d1.d_e_l_e_t_ <> '*'
AND s9.b9_data = (SELECT MAX(b9_data) FROM SB9010)
PS: 不能在update中使用别名,只能在FROM之后使用。
您将需要使用语法符合 Informix 支持的 UPDATE 语句。
一般形式为:
UPDATE target
SET (col1, …, colN) = ((SELECT val1, …, valN FROM WhereEver …))
WHERE …
SET 子句右侧的双括号是有意且必要的。主 UPDATE 中的 WHERE 子句必须确保只选择将使用 SELECT 语句中的值更新的行。如果不这样做,没有匹配条目的行将 col1, …, colN
设置为 NULL,这很少是我们想要的。
尝试将此应用到您的查询中,可能与此类似:
UPDATE da1010 AS d1
SET (da1_prcven, datvig) = ((SELECT s9.b9_cm1, s9.b9_data
FROM sb1010 s1
JOIN sb9010 S9 ON (s9.b9_filial = '0101' AND
s9.b9_cm1 <> 0 AND
s9.b9_cod = s1.b1_cod AND
s9.b9_local = s1.b1_locpad AND
s9.d_e_l_e_t_ <> '*')
WHERE d1.da1_codtab = '009'
AND d1.da1_datvig < s9.b9_data
AND d1.da1_codpro = s1.b1_cod
AND d1.d_e_l_e_t_ <> '*'
AND s1.d_e_l_e_t_ <> '*'
AND s9.b9_data = (SELECT MAX(b9_data) FROM sb9010)
))
WHERE d1.da1_codtab = '009'
AND d1.d_e_l_e_t_ <> '*';
这不正确,但足以纠正它运行并更新目标 table、d1010
。
用于测试的示例 SQL。请注意,问题中的 SQL 指的是 da1010
table 中的 datvig
和 da1_datvig
。我认为 datvig
可能是一个错字,但由于未提供大纲架构,因此很难确定。
CREATE TABLE da1010
(
da1_prcven INTEGER,
datvig INTEGER, -- Original references both datvig and da1_datvig
da1_datvig INTEGER, -- Original references both datvig and da1_datvig
da1_codpro INTEGER,
da1_codtab CHAR(3),
d_e_l_e_t_ CHAR(1)
);
CREATE TABLE sb1010
(
b1_cod INTEGER,
b1_locpad INTEGER,
d_e_l_e_t_ CHAR(1)
);
CREATE TABLE sb9010
(
b9_cm1 INTEGER,
b9_data INTEGER,
b9_cod INTEGER,
b9_local INTEGER,
b9_filial CHAR(4),
d_e_l_e_t_ CHAR(1)
);
INSERT INTO da1010 VALUES(100, 1000, 100, 100, '009', 'N');
INSERT INTO da1010 VALUES(102, 1000, 101, 102, '009', 'N');
INSERT INTO da1010 VALUES(102, 1000, 101, 102, '009', '*');
INSERT INTO sb1010 VALUES(100, 20, 'N');
INSERT INTO sb1010 VALUES(100, 30, '*');
INSERT INTO sb1010 VALUES(101, 99, 'N');
INSERT INTO sb1010 VALUES(102, 40, 'N');
INSERT INTO sb1010 VALUES(102, 50, '*');
INSERT INTO sb9010 VALUES(2345, 3456, 100, 20, '0101', 'N');
INSERT INTO sb9010 VALUES(2344, 3466, 102, 40, '0101', 'N');
INSERT INTO sb9010 VALUES(2343, 3476, 100, 20, '0101', 'N');
INSERT INTO sb9010 VALUES(2342, 3486, 100, 20, '0101', 'N');
INSERT INTO sb9010 VALUES(2341, 3496, 101, 40, '0101', 'N');
INSERT INTO sb9010 VALUES(2345, 3456, 100, 20, '0101', '*');
INSERT INTO sb9010 VALUES(2344, 3466, 102, 40, '0101', '*');
INSERT INTO sb9010 VALUES(2343, 3476, 100, 20, '0101', '*');
INSERT INTO sb9010 VALUES(2342, 3486, 100, 20, '0101', '*');
INSERT INTO sb9010 VALUES(2341, 3496, 101, 40, '0101', '*');
之前:
SELECT * FROM da1010;
100|1000|100|100|009|N
102|1000|101|102|009|N
102|1000|101|102|009|*
之后:
SELECT * FROM da1010;
||100|100|009|N
||101|102|009|N
102|1000|101|102|009|*
如您所见,两行中的 da1_prcven
和 datvig
列已被取消。这表明了一些事情:
- 我没有生成满足更新条件的数据。
- 我没有充分选择主 UPDATE 中的 WHERE 子句。它很可能需要来自主 WHERE 子句中 SET 子句的 SELECT 语句的重要部分。
但是,我无法确切地了解 UPDATE 应该做什么,所以我不愿意花更多的时间来猜测接下来会发生什么。
另一种选择是使用 MERGE:
MERGE INTO dept d
USING dept_online o
ON (d.deptno = o.deptno)
WHEN MATCHED THEN
UPDATE SET d.dname = o.dname, d.loc = o.loc;
经过大量的query和attentation研究informix的文档后,我得出了问题的解决方案,我在这里与大家分享以完成主题。
CREATE PROCEDURE proc_update_table()
DEFINE x_cod varchar(15) ; --declaration local variable
DEFINE x_date varchar(8) ;
DEFINE x_vlr float ;
FOREACH --selects rows according to query
SELECT b9_cod, b9_data, b9_cm1
INTO x_cod, x_date, x_vlr
FROM SB9010
INNER JOIN DA1010 ON (b9_cod = da1_codpro AND da1_datvig < b9_data)
INNER JOIN SB1010 ON (b9_cod = b1_cod AND b9_local = b1_locpad)
WHERE b9_cm1 <> '0'
AND SB9010.d_e_l_e_t_ <> '*'
AND b9_data = (SELECT MAX(b9_data) FROM SB9010)
UPDATE DA1010 --update fields with variables values
SET da1_prcven = x_vlr, da1_datvig = x_date
AND da1_codpro = x_cod
AND da1_datvig < x_date
AND d_e_l_e_t_ <> '*';
END FOREACH;
END PROCEDURE;