Plsql PL/SQL:创建函数:标识符无效
我通过Oracles github()上的docker映像构建了一个oracle 19c ee数据库。我试图按照他们的例子来创建函数 我完全照搬了他们的例子。设置表和数据:Plsql PL/SQL:创建函数:标识符无效,plsql,Plsql,我通过Oracles github()上的docker映像构建了一个oracle 19c ee数据库。我试图按照他们的例子来创建函数 我完全照搬了他们的例子。设置表和数据: CREATE TABLE orders ( customer_id number(10), order_total NUMBER(11,2) ); INSERT INTO orders (customer_id, order_total) VALUES (1, 200.01) 实际功能: CREATE F
CREATE TABLE orders (
customer_id number(10),
order_total NUMBER(11,2)
);
INSERT INTO orders (customer_id, order_total) VALUES (1, 200.01)
实际功能:
CREATE FUNCTION get_bal(acc_no IN NUMBER)
RETURN NUMBER
IS acc_bal NUMBER(11,2);
BEGIN
SELECT order_total
INTO acc_bal
FROM orders
WHERE customer_id = acc_no;
RETURN(acc_bal);
END;
然而,当我尝试创建函数时,我总是遇到这个错误
Query 2 ERROR: ORA-06550: line 5, column 27:
PL/SQL: ORA-00904: "ACC_NO": invalid identifier
ORA-06550: line 2, column 7:
PL/SQL: SQL Statement ignored
ORA-06550: line 6, column 7:
PLS-00372: In a procedure, RETURN statement cannot contain an expression
ORA-06550: line 6, column 7:
PL/SQL: Statement ignored
我做错了什么?这个例子对我很有用。你一定打错了什么东西。您确定您的功能与手册中的功能完全相同吗 ORA-00904:“附件编号”:无效标识符 建议声明
acc\u bal编号(11,2)代码>缺失或不同
PLS-00372:在过程中,返回语句不能包含表达式
指示代码是过程,而不是函数
SQL> CREATE TABLE orders (
2 customer_id number(10),
3 order_total NUMBER(11,2)
4 );
Table created
SQL> INSERT INTO orders (customer_id, order_total) VALUES (1, 200.01);
1 row inserted
SQL> CREATE FUNCTION get_bal(acc_no IN NUMBER)
2 RETURN NUMBER
3 IS acc_bal NUMBER(11,2);
4 BEGIN
5 SELECT order_total
6 INTO acc_bal
7 FROM orders
8 WHERE customer_id = acc_no;
9 RETURN(acc_bal);
10 END;
11 /
Function created
SQL> select get_bal(1) from dual;
GET_BAL(1)
----------
200.01
顺便说一句,虽然我是Oracle文档的忠实粉丝,而且这个例子很好地说明了如何创建PL/SQL函数,但我认为它可以改进:
- 为了可读性,最好给每个声明指定自己的行,因此第3行最好用
acc_bal NUMBER(11,2)分成两行代码>在它自己的行上
是
和,因为
关键字在这里是可互换的,但肯定是创建。。。因为
(类似于您可能用来创建表或视图的内容)比创建更容易阅读。。。是
- 可以理解,作者不想在解释之前引入
%type
使示例复杂化,但更高级的版本将使用acc\u bal orders.order\u total%type
使acc_bal
从表列继承其数据类型,而不是硬编码。这适用于函数中使用的所有三个值
- 参数和变量的名称是可以的-它们至少是清晰的-但是当使用与表列相同的参数和变量命名模式时,会有危险。总有一天,你会输入
其中c.customer\u id=customer\u id
,并想知道为什么你得到的行数比预期的多。同样可以理解的是,作者不想在第一个例子中涉及到整个讨论,但这是值得思考的。您可以在函数中使用get\u bal.acc\u no
,或者对参数和变量使用camelCase,或者对“参数”等使用p\u
前缀
- 布局的基本规则是打开和关闭关键字,如
if/else
和begin/end
,应该左对齐。第10行的END
在其开口BEGIN
下未对齐。我想在第一行之后缩进整个内容是一个有效的个人布局选择,但对我来说,它没有添加任何内容
- 最好在每个SQL语句周围留下空行,以避免形成一堵坚实的文本墙。就我个人而言,我希望在第9行的
返回之前有一个空行
RETURN
子句不需要任何括号。编译器忽略第9行的多余括号。我会失去他们的
- 好的做法是(尽管是可选的)将过程/函数名称包含在结束
中,因此第10行将成为结束get\u bal代码>
- COBOL风格的大写习惯在业界很普遍,但没有必要这样做。(PL/SQL的语法以Ada为基础而闻名,不过也有人指出ALGOL和PL/1——从来没有人用大写字母写过这些语法。)我会通过将整件事小写来提高可读性
通过这些更改,我得到了以下结果:
create or replace function get_bal
( inAccNo in orders.customer_id%type )
return orders.order_total%type
as
accBal orders.order_total%type;
begin
select order_total into accBal
from orders
where customer_id = inAccNo;
return accBal;
end;
有趣!那太有帮助了。我试图使用TablePlus
创建函数,所以我怀疑它单独运行了每条语句?当我在sqlplus
中运行它时,它会工作。谢谢在什么情况下,是
和作为
关键字是不可互换的?文档中没有涉及到这一点,它们在创建PL/SQL对象(过程、函数、包、类型)时是可以互换的,这可能就是为什么PL/SQL手册没有对此进行讨论的原因。在创建表和视图或SQL查询中的列别名时,它们是不可互换的。