【问题标题】:Getting invalid identifier and SQL ignored errors in stored procedure in Oracle在 Oracle 的存储过程中获取无效标识符和 SQL 忽略错误
【发布时间】:2014-09-09 06:33:28
【问题描述】:

我正在尝试创建一个存储过程,以便将一些数据插入到 Oracle 11g 中的某个表中。

为此,我需要从该用户的最新插入中读取最后一个金额,然后将其添加到我的新值中并将更改保存为新行,如果发生任何类型的异常,只需回滚即可。到目前为止,这是我想出的:

CREATE OR REPLACE PROCEDURE MYTESTDB.INSERT_INTO_TESTBANK
(
  ID IN TBLTESTBANK.ID%TYPE,
  USERID IN TBLTESTBANK.USERID%TYPE,
  TYPE IN TBLTESTBANK.TYPE%TYPE,
  AMOUNT IN TBLTESTBANK.AMOUNT%TYPE,
  DATETIMESTAMP IN TBLTESTBANK.DATETIMESTAMP%TYPE,
  TRANSACTION_ID IN TBLTESTBANK.IDTRANS%TYPE,
  TOTAL_MONEY IN TBLTESTBANK.TOTALMONEY%TYPE,
  COMPUTED_HASH IN TBLTESTBANK.HASH%TYPE
  )
IS

BEGIN
  DECLARE 
  LastAmount TBLTESTBANK.TOTALMONEY%TYPE;

  BEGIN
      SELECT TBLTESTBANK.TOTALMONEY INTO LASTAMOUNT
      FROM 
      (
        SELECT TBLTESTBANK.ID 
        FROM TBLTESTBANK tblbnk
        WHERE tblbnk.USERID = USERID 
        order by max(tblbnk.DATETIMESTAMP)
      ) 
      where ROWNUM<2;
      EXCEPTION WHEN NO_DATA_FOUND 
      THEN LastAmount := 0;        
   END;

  LastAmount := LastAmount+ AMOUNT;

  INSERT INTO TBLTESTBANK (ID, USERID, TYPE, LastAmount,
                            DATETIMESTAMP, IDTRANS, TOTALMONEY, HASH
                            )
  VALUES (ID, USERID, TYPE, AMOUNT, DATETIMESTAMP, TRANSACTION_ID, TOTAL_MONEY, COMPUTED_HASH); 
    COMMIT;
 EXCEPTION WHEN OTHERS
  THEN
  ROLLBACK;
END;
/

每当我尝试测试它时,我会在第一个 SELECT 下得到一条红色的摆动线,然后在内部 select 语句中得到 TESTBANK.ID。对于它说的 select 命令,忽略 sql 语句,对于 TESTBANK.ID 它说无效标识符!

它也不允许我添加两个变量,并一直说 LastAmount 必须声明。

这些是我得到的错误:

     Error(19,7): PL/SQL: SQL Statement ignored
     Error(22,16): PL/SQL: ORA-00904: "TBLTESTBANK"."ID": invalid identifier
     Error(32,3): PLS-00201: identifier 'LASTAMOUNT' must be declared
     Error(32,3): PL/SQL: Statement ignored
     Error(34,3): PL/SQL: SQL Statement ignored
     Error(34,47): PL/SQL: ORA-00904: "LASTAMOUNT": invalid identifier

【问题讨论】:

  • 请发布完整和准确的错误信息。
  • @a_horse_no_name:我用我得到的错误更新了问题

标签: stored-procedures oracle11g


【解决方案1】:

你有两个问题:

在您的选择语句中:

   SELECT TBLTESTBANK.ID 
    FROM TBLTESTBANK tblbnk
    WHERE tblbnk.USERID = USERID 
    order by max(tblbnk.DATETIMESTAMP)

您已为表TBLTESTBANK 指定别名tblbnk,因此您必须在整个语句中使用别名:

   SELECT tblbnk.ID  -- use the correct alias here
    FROM TBLTESTBANK tblbnk
    WHERE tblbnk.USERID = USERID 
    order by max(tblbnk.DATETIMESTAMP)

第二:

INSERT 语句中,您必须列出 而不是值。

INSERT INTO TBLTESTBANK (ID, USERID, TYPE, LastAmount,
                        DATETIMESTAMP, IDTRANS, TOTALMONEY, HASH
                        )

应该是:

INSERT INTO TBLTESTBANK (ID, USERID, TYPE, AMOUNT, --- column name instead of variable name
                        DATETIMESTAMP, IDTRANS, TOTALMONEY, HASH
                        )

当然你需要在值部分使用LastAmount,而不是AMOUNT

一般来说,让变量与您在过程中使用的表的列同名并不是一个好主意。用列来隐藏变量很容易。您应该重命名变量以避免出现任何问题。

编辑(一开始我没有注意到)。

您的代码结构也有错误。存储过程(或函数)没有DECLARE 部分:

您的声明需要如下所示:

CREATE OR REPLACE PROCEDURE MYTESTDB.INSERT_INTO_TESTBANK
(
  ....
)
IS
  -- no DECLARE
  -- variables right after the IS keyword
  LastAmount TBLTESTBANK.TOTALMONEY%TYPE;
BEGIN

...
END;

【讨论】:

  • 非常感谢。这解决了选择问题,但我仍然有 LATESTAMOUNT 必须声明错误!
  • @Hossein 是否更改了 insert 语句的列列表?
  • 是的,我做到了。我还更改了变量名称,以便它们不会相互碰撞或阴影。:这是最新的更改:pastebin.com/tLwNZzfC
  • @Hossein:查看我的编辑。无意冒犯,但您应该真的阅读 PL/SQL 手册(再次)。所有这些语法元素都在此处详细解释并附有示例。
  • 谢谢,我很感激。是的,你是对的,实际上我只是对 Oracle 有非常基本的了解。我也只是在学习。
【解决方案2】:

您可以尝试以下选择查询以获取最新记录。

SELECT TB.TOTALMONEY INTO LASTAMOUNT
FROM 
TESTBANK TB
WHERE
TB.USERID=USERID
AND
DATETIMESTAMP= (SELECT MAX       (TB2.DATETIMESTAMP) FROM TESTBANK TB2 
WHERE TB2.USERID=USERID);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多