Oracle创建一个自定义函数,返回emp表的行数,请问哪位大神知道啊?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle创建一个自定义函数,返回emp表的行数,请问哪位大神知道啊?相关的知识,希望对你有一定的参考价值。
问题2:oracle创建一个存储过程,当传入emp表的ename字段的一个值时,返回salgrade表中的grade字段。
1
create or replace function f_countreturn int
is
result int;
begin
select count(*) into result from emp;
return result;
end;
调用
select f_count() from dual
2
create or replace procedure p_sal(v_ename varchar2)
is
v_grade int;
begin
select b.grade into v_grade from emp a,salgrade b where a.sal between b.losal and b.hisal and a.ename=v_ename;
DBMS_OUTPUT.PUT_LINE(v_grade);
end;
执行
beginp_sal(\'某个人名\');
end;追问
2.建立一个触发器,当对emp表进行dml操作的时候,会将操作记录记录到emp_log表中,oper_user列存放操作的用户名,oper_type列存放操作类型(insert,delete,update),oper_time存放操作时间。
追答你确定这是最后一个问题了么?
create or replace trigger t_empafter insert or update or delete
on emp
for each row
begin
case when updating then
insert into emp_log values (user,\'update\',sysdate);
when deleting then
insert into emp_log values (user,\'delete\',sysdate);
when inserting then
insert into emp_log values (user,\'insert\',sysdate);
end case;
end;追问
回答的很好,帮了我大忙了,还有最后一个问题怎么创建游标呢: 创建一个游标,存放emp表中的数据,并遍历此游标。小弟是菜鸟,请多多指教啊
追答DECLARECURSOR emp_cursor IS
SELECT * FROM emp;
emp_record emp_cursor%ROWTYPE;
BEGIN
OPEN emp_cursor;
loop
FETCH emp_cursor
INTO emp_record;
EXIT WHEN emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(emp_record.empno || \',\' || emp_record.ename || \',\' ||
emp_record.job || \',\' || emp_record.mgr || \',\' ||
emp_record.hiredate || \',\' || emp_record.sal || \',\' ||
emp_record.comm || \',\' || emp_record.deptno);
end loop;
CLOSE emp_cursor;
END; 参考技术A 你要给出EMP和salgrade的关联关系才能处理
Oracle - ORA-01422:精确提取返回的行数超过了请求的行数
【中文标题】Oracle - ORA-01422:精确提取返回的行数超过了请求的行数【英文标题】:Oracle - ORA-01422: exact fetch returns more than requested number of rows 【发布时间】:2011-12-09 15:33:23 【问题描述】:我仍在为一家小型零售店开发此数据库(谢天谢地,这是一个场景!),目前正在尝试使用触发器解决此问题。
相关实体是客户、付款和订单。付款是其他两者之间的链接实体,因此一个客户可以进行多次付款,而一个订单可能进行多次付款(不寻常但仍然可能),这一切都很好。
触发器:
CREATE OR REPLACE TRIGGER Check_Payment_Status
BEFORE UPDATE OF Order_Status ON Customer_Order
for each row
DECLARE paymentStatus payment.payment_status%type;
BEGIN
select payment.payment_status into paymentStatus
from payment
where order_no = :new.order_no;
IF (paymentStatus ='Failed' OR paymentStatus IS NULL ) then
RAISE_APPLICATION_ERROR(-20103, 'The full payment has not been made so the order cannot be processed further until then.');
update customer_order set order_status='Delayed' where order_no= :new.order_no;
END IF;
IF (paymentStatus ='Successful' ) then
update payment set payment_date=SYSDATE where order_no= :new.order_no;
END IF;
END;
.
run
目前还可以。基本上,在将客户的订单标记为“已发货”之前,付款状态必须为“成功”。如果它为空或“失败”,则触发器将类似于“哦,不,你没有!” (但用更正式的话来说)按预期工作。但是,如果有人应用业务规则“一个订单可以有很多付款”,则触发器需要检查所有相关付款,这是我收到此错误的地方,因为 SELECT INTO
语句打算只返回一行。
我已经阅读了一些关于 Cursors 的内容,但我认为我在这里走得太远了 - 请有人提出一些解决方案吗?
【问题讨论】:
如果您只是按照触发器的名称检查付款状态,为什么要在此处更新 payment_date?这似乎不合适 - 您不会在将 payment_status 设置为成功的同一时间点更新付款日期吗? 【参考方案1】:好吧,如果一个订单可以有多次付款,您如何确定是否全额付款?大概每笔付款都有金额,订单有总金额到期,所以需要检查是否全额支付。在我看来,您可以通过获取所有成功付款的总和然后将其与应付总额进行比较来做到这一点。基本查询是:
SELECT SUM(payment_amount)
INTO total_payment_amount
FROM payment
WHERE order_no = :new.order_no
AND payment_status = 'Successful';
【讨论】:
【参考方案2】:总的来说,您有很多应用程序级逻辑绑定到触发器中,这会给您带来很多麻烦,因为您不知道何时以及为什么更新值您的相关表格。
Dave Costa 对处理付款有一个很好的建议,我会创建一个或多个相关的 PL/SQL 包,其中包含明确编写的函数和过程,用于处理您尝试在此触发器中执行的应用程序级逻辑.
应该很少使用触发器——通常是在您设置序列的主键或审核对表的访问时。
【讨论】:
【参考方案3】:我知道这是一个老问题,但今天在客户端生产数据库中出现了类似问题。有时按主键(可能是序列号)按降序排序并使用“rownum=1”可能很有用。当然,您应该找出为什么您有多个符合条件的记录,并修复您的应用程序中允许它的错误。
【讨论】:
以上是关于Oracle创建一个自定义函数,返回emp表的行数,请问哪位大神知道啊?的主要内容,如果未能解决你的问题,请参考以下文章
为啥选择单个属性返回的行数少于选择 Oracle SQL 中的所有列