用merge into 的时候提示 ORA-01733: virtual column not allowed here

本文解决了一个在使用Oracle数据库时遇到的问题:ORA-01733错误。该错误出现在尝试使用MERGE INTO语句更新数据时。通过调整SQL语句并正确引用表字段而非变量,成功解决了这一问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Error: PL/SQL: ORA-01733: virtual column not allowed here
Line: 81
Text: MERGE INTO SvcOrderProfit


Error: PL/SQL: SQL Statement ignored
Line: 81

Text: MERGE INTO SvcOrderProfit


用merge into 的时候提示

REF  :http://www.cnblogs.com/dongsheng/p/4384754.html


问题代码:

 WHEN MATCHED THEN
    UPDATE
       SET IncomeRMB                    = pos_2,
           CostRMB                      = pos_3;/*,
           v_dIncomeUSDFee              = pos_4,
           v_dIncomeUSDAccount          = pos_5,
           v_dlCostUSDFee               = pos_6,
           v_dlCostUSDAccount           = pos_7,
           v_dIncomeRMBSales            = pos_8,
           v_dCostRMBSales              = pos_9,


ROOT CAUSE 本来左边应该是表名,从SQL 转过来的时候却弄成了变量。所以报错 

solution  :


表字段的保留, 非表字段的SELECT INTO 到变量里面:

      SELECT NVL((SELECT SUM(SvcOrderFee.NoTaxFeeAmount)
                              FROM SvcOrderFee
                             WHERE SvcOrderFee.CurrencyType = 0
                               AND SvcOrderFee.CreditDebitType = 0
                               AND (SvcOrderFee.AccountType = 2 OR
                                   SvcOrderFee.AccountType = 3)
                               AND SvcOrderFee.OrderBillID = v_lOrderBillID),
                            0)

INTO         v_dCostRMBSales  
                   FROM DUAL;




### ORA-00933: SQL command not properly ended 错误的原因与解决方案 在PL/SQL中,如果遇到 `ORA-00933: SQL command not properly ended` 错误,通常表示SQL语句的语法不符合Oracle数据库的要求。该错误提示表明SQL语句在某个地方没有被正确结束,或者存在语法问题。以下是常见的原因和对应的解决方案。 #### 原因与解决方法 1. **使用了不支持的关键字或语法** Oracle数据库对SQL语法有特定的要求,某些在其他数据库(如PostgreSQL或MySQL)中允许的语法可能在Oracle中不被支持。例如,在Oracle中,表别名不需要使用 `AS` 关键字。如果SQL语句中使用了 `AS` 来定义表别名,会导致ORA-00933错误[^2]。 - **解决方案**:移除 `AS` 关键字,直接使用空格定义表别名。 ```sql -- 错误写法 SELECT T.code AS CODE FROM info_table AS T; -- 正确写法 SELECT T.code AS CODE FROM info_table T; ``` 2. **SQL语句中关键字前后缺少空格** 在编写SQL语句时,关键字(如 `SELECT`, `FROM`, `WHERE`)前后如果没有适当的空格,可能导致Oracle解析错误。 - **解决方案**:确保关键字前后有适当的空格。例如,避免写成 `SELECT*FROM`,而应写成 `SELECT * FROM`。 3. **SQL语句中缺少关键字或多了某个关键字** 如果SQL语句中缺少必要的关键字(如 `AND`, `OR`)或者多了一个关键字,会导致语句无法正确解析。 - **解决方案**:仔细检查SQL语句中的逻辑条件和关键字使用,确保没有多余或缺失的关键字。 4. **SQL语句中缺少关键字或多了某个标点符号** 标点符号(如逗号 `,`、分号 `;`)的缺失或多余也可能导致ORA-00933错误。 - **解决方案**:检查SQL语句中的标点符号,确保其使用正确。 5. **不同数据库之间的语法差异** 不同数据库(如MySQL、PostgreSQL、Oracle)对SQL语法的支持可能有所不同。某些在其他数据库中运行正常的SQL语句可能在Oracle中报错。 - **解决方案**:根据Oracle的SQL语法要求调整语句。例如,子查询别名在Oracle中不能使用 `AS`,而需要直接使用表别名[^5]。 ```sql -- 错误写法 SELECT SUM(in_port) AS total_in_port FROM ( SELECT CASE WHEN yy = 40 THEN COUNT(a.cntr) * 2 WHEN yy = 20 THEN COUNT(a.cntr) * 1 ELSE COUNT(a.cntr) END AS in_port FROM xx a WHERE a.dang_id = '1' GROUP BY CNTR_SIZ_COD ) AS subquery; -- 正确写法 SELECT SUM(in_port) AS total_in_port FROM ( SELECT CASE WHEN yy = 40 THEN COUNT(a.cntr) * 2 WHEN yy = 20 THEN COUNT(a.cntr) * 1 ELSE COUNT(a.cntr) END AS in_port FROM xx a WHERE a.dang_id = '1' GROUP BY CNTR_SIZ_COD ) subquery; ``` 6. **PL/SQL块中的SQL语句格式问题** 在PL/SQL块中执行SQL语句时,需要注意语句的格式和分隔符。例如,在PL/SQL中,SQL语句不需要以分号 `;` 结尾。 - **解决方案**:确保PL/SQL块中的SQL语句符合Oracle的语法要求,并避免不必要的分号。 #### 示例:修复PL/SQL中的ORA-00933错误 假设在PL/SQL中执行以下语句时遇到ORA-00933错误: ```sql BEGIN UPDATE b_dispatch SET ReferenceNum = ( CASE WHEN NVL(fno, ' ') = ' ' THEN fno WHEN fno = '〔〕' THEN '' ELSE REPLACE(k.FileNo, '%s', fno) END ) FROM b_dispatch b LEFT JOIN k_docimage k ON b.ModName = k.Name WHERE b.ID = '{4589EEC4-9E7F-4CBF-947E-8D47FDE325AC}' AND (fno <> ReferenceNum); END; ``` 上述语句中的 `FROM` 子句在PL/SQL的 `UPDATE` 语句中是不被支持的,这会导致ORA-00933错误。 - **解决方案**:使用子查询或 `MERGE` 语句来实现更新操作。 ```sql BEGIN UPDATE b_dispatch b SET ReferenceNum = ( SELECT CASE WHEN NVL(b.fno, ' ') = ' ' THEN b.fno WHEN b.fno = '〔〕' THEN '' ELSE REPLACE(k.FileNo, '%s', b.fno) END FROM k_docimage k WHERE b.ModName = k.Name ) WHERE b.ID = '{4589EEC4-9E7F-4CBF-947E-8D47FDE325AC}' AND (b.fno <> b.ReferenceNum); END; ``` ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值