UPDATE 命令出现语法错误

Posted

技术标签:

【中文标题】UPDATE 命令出现语法错误【英文标题】:A syntax error has occurred on UPDATE command 【发布时间】:2018-06-13 19:50:20 【问题描述】:

这是 Informix UPDATE 的正确语法吗?

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)

当我发出执行查询的命令时,编辑器返回语法错误(-201:发生语法错误)。

【问题讨论】:

错误是什么? 错误信息是什么?只是说' Informix 语法不包括 FROM 子句 (ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0/…)。你的意图还不清楚。 该消息仅说明语法错误,不显示更多信息。 Gordon,查询必须根据 where 块中的条件更新所有条目。我会根据IBM文档再次修改代码。谢谢大家,我会继续努力的。 我认为您需要使用的一般形式类似于此更新表集 (col1, col2) = (select newcol1, newcol2 from ...) 只是不确定您的 where 子句是否会仅在 select 上,或者如果您只想更新原始表中的某些行。 【参考方案1】:

我看到你用请求的信息更新表 da1010,但在那一行:

SET d1.da1_prcven = s9.b9_cm1, d1.datvig = s9.b9_data

您是否更新了表 D1 的信息而不是表 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:更新中不能使用别名,只能在FROM之后使用。

【讨论】:

希望对你有所帮助。 这无济于事; Informix 无法识别带有 FROM 子句的这种语法 - 请参阅 Informix SQL 语法手册中的 UPDATE 语句。【参考方案2】:

另一种选择是使用 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;  

【讨论】:

【参考方案3】:

您需要使用语法与 Informix 支持的语法相匹配的 UPDATE 语句。

它将具有以下一般形式:

UPDATE target
   SET (col1, …, colN) = ((SELECT val1, …, valN FROM WhereEver …))
 WHERE …

SET 子句的 RHS 上的双括号是经过深思熟虑和必要的。主 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_ <> '*';

这是不正确的,但它足够接近纠正它运行并更新目标表d1010

用于测试的示例 SQL。请注意,问题中的 SQL 指的是 da1010 表中的 datvigda1_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_prcvendatvig 列已无效。这表明了几件事:

    我未能生成满足更新条件的数据。 我没有使主UPDATE 中的WHERE 子句具有足够的选择性。它很可能需要主要 WHERE 子句中的 SET 子句中的 SELECT 语句的很大一部分。

但是,我无法准确判断 UPDATE 应该做什么,所以我不愿意花更多时间去猜测接下来会发生什么。

【讨论】:

感谢所有回答的人,但我的问题还是没有找到满意的解决方案,我会继续“战斗”,一旦找到解决方案我就把它带给你 【参考方案4】:

在研究informix的文档后,我在query和attentation方面花了很多功夫,得出了问题的解决方案,我在这里与大家分享以敲定主题。

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;

【讨论】:

以上是关于UPDATE 命令出现语法错误的主要内容,如果未能解决你的问题,请参考以下文章

MySQL:存储过程语法错误

为啥cad安装会出现命令行语法错误

求助大神,命令行选项语法错误,怎么解决

asp.NET 的update错误,请高人进来看下

Insert into 语句语法错误

INSERT INTO 语句的语法错误