如何用oracle语句得到如下格式:可能需要点耐心

zkvistor 2009-06-26 06:07:05
product(产品表:)
prodid(varchar2) 产品ID 主键
prodname(varchar2) 产品名称
hprice number(10,2)价钱

prodid prodname hrpice
129004 嘉源V300水墨黑 699

orderhist(订单表)
orderid 订单ID 主键
mailid 邮件编号
contactid 联系人ID
result 订单反馈结果 (上述字段均为varchar2类型)
。。。。
orderdet(订单详情表)
orderdetid 订单详情ID
orderid 订单ID(外键)
prodid 产品ID
prodname 产品名称
contactid 订购人ID
upnum(number) 订购个数
uprice(number) 产品原价
orderde(date) 订购日期
。。。。。

phone 电话表
phoneid varchar2 电话ID 主键
contactid varchar2 客户ID
phn1 varchar2 电话区号(可为空)
phn2 varchar2 电话号码 (可为空)
phn3 varchar2 电话扩展号(可为空)
phoneid contactid phn1 phn2 phn3
402312 1001 15876565656
402313 1001 01087654321
一个人可以拥有多个联系方式


未标注的都是varchar2类型
现在要得到如下格式:

品名
嘉园V300水墨黑*1(数量)


select orderhist.crdt as 订购日期,
orderhist.orderid as 订单号,
contact.contactid as 客户编号,
contact.name as 客户姓名,NewFormatPhone(Contact.contactid) as 客户电话, address.zip as 邮编,
fun_getprovincename(orderhist.provinceid) as 省份,
orderhist.prodprice as 货运总额,
orderhist.mailprice as 运费,
orderhist.totalprice as 总金额,
grp.grpname as 组名,
usr.name as 员工姓名,
Fun_GetDDFK(orderhist.result) as 订单反馈,
fun_getcpzt(orderhist.status) as 订单状态,
orderhist.fbdt as 反馈日期,
fun_getpsfs(orderhist.mailtype) as 订购方式,
Fun_GetFKFS(orderhist.paytype) as 付款方式,
decode(orderhist.bill, '1', '需要', '不需要') as 要发票,
address.address as 客户地址,
orderhist.payer as 发票抬头,
topic.dsc as 客户备注,
orderhist.mailid as 邮件编号,
orderhist.note as 订单备注,
orderhist.parcdt as 投递日期
From orderhist, CONTACT, ems, PHONE, Address, Topic, usr, grp
where orderhist.contactid = contact.contactid
and orderhist.spellid = ems.spellid(+)
and phone.phoneid =
(select min(phoneid)
from phone
where phone.contactid = orderhist.getcontactid)
and orderhist.contactid = address.contactid
and topic.contactid(+) = contact.contactid

上面的一段代码得到的效果如下:
订购日期 订单号 客户编号 客户姓名 客户电话 。。。。。。
2009-06-26 17:53:00 54321 10214544 张三 13009876678 027-87656789 。。。。。。。

NewFormatPhone(Contact.contactid) as 客户电话 代码如下:
create or replace function NewFormatPhone(sContactid in phone.contactid%type)

return varchar2 is Result varchar2(2000);
v_Phn1 varchar2(20);
v_Phn2 varchar2(30);
v_phn3 varchar2(30);
v_Phone varchar2(100);

cursor c_Phone is
select decode(phone.phn1,'0','',phone.phn1) || decode
(phone.phn1,'','','0','','-') || phone.phn2 || decode(phone.phn3,'','','0','','-')
|| decode(phone.phn3,'0','',phone.phn3)||decode(phone.phonetypid,'','','')
from phone,(select id,dsc from names where tid='PHONETYP') tPhoneType
where phone.phonetypid=tPhoneType.id(+) and phone.contactid=sContactid;
begin
open c_Phone;
loop
fetch c_Phone into v_Phone;
exit when c_Phone%notfound;
Result := Result || ' ' || v_Phone;
end loop;
close c_Phone;

return(Result);
end NewFormatPhone;

上面只起到一个抛砖引玉的作用,
最后我要得到的结果为:
订购日期 订单号 品名 客户姓名 。。。。。。。
2009-06-25 54333 诺基亚N72黑色*1 诺基亚N79黑色*2 李四 。。。。。。。。
主要就是这个品名这一块,一个订单里可能有多个产品,就和电话有点相似,请各位指点
...全文
90 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
zkvistor 2009-07-10
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20090627/15/09a158ee-637c-4083-8220-6a4da35a4a51.html
该贴和这个是同一问题,可以看一下 总共140分

如果只查询3条记录出来 也报同样的错误:

ORA-06502 PL/SQL 数字或值错误,ORA-06512
数字或值错误 指向 returnProName:=returnProName ||' ' || v_result;
这一行

这个错误大意是说 查询得到的结果超出了函数返回值的范围
函数返回值类型为varchar2(3000),如果只查3个值得话是绝对不会超出范围的,

顶一下 。。。。。。

这是为什么咧?
zkvistor 2009-07-01
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 hebo2005 的回复:]
如果对品名输出顺序没什么要求,可以用WMSYS.WM_CONCAT函数来实现
[/Quote]

最后得到的结果格式如下:
订购日期 订单号 客户姓名 客户电话 省份 总金额 品名 员工姓名 订单反馈 订单状态 订购方式
2009-06-29 56 李四 13009876096 黑龙江 333 诺基亚N79黑色*1(数量) 诺基亚5800*2 张三 无反馈 订购 宅急送


cab1225 2009-06-30
  • 打赏
  • 举报
回复
那有可能是returnProName超过了定义的长度了。你可以把 dbms_output.put_line(returnProName); 拿走,加个判断,就是大于1500(定义的长度)才打出来信息。看有没有这条信息打出来。
inthirties 2009-06-30
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 zkvistor 的回复:]
引用 7 楼 inthirties 的回复:



那有可能是returnProName超过了定义的长度了。你可以把 dbms_output.put_line(returnProName); 拿走,加个判断,就是大于1500(定义的长度)才打出来信息。看有没有这条信息打出来。


加了,没有任何信息
[/Quote]

在sqlplus里执行set serveroutput on;
或者在plsql里加入dbms_output.enable();

是信息可以输出。
xjwy 2009-06-30
  • 打赏
  • 举报
回复
这里是解决难题的地方,抛砖引玉的地方,寻找思路的地方,不是帮你工作的地方
zkvistor 2009-06-30
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20090627/15/09a158ee-637c-4083-8220-6a4da35a4a51.html

这个帖子和该贴是同一个问题,大家可以看一看
hebo2005 2009-06-30
  • 打赏
  • 举报
回复
如果对品名输出顺序没什么要求,可以用WMSYS.WM_CONCAT函数来实现
carefree_fish 2009-06-30
  • 打赏
  • 举报
回复
好长的语句啊。。。顶
thesecretblue 2009-06-30
  • 打赏
  • 举报
回复
up!!!!
zkvistor 2009-06-29
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 inthirties 的回复:]
引用 6 楼 inthirties 的回复:

指向returnProName:=returnProName ||' ' || v_result;这一行

可能是指向returnProName的长度已经超过了定义的长度了。


你可以在循环里output一下returnProName的长度,看是循环到什么时候操过长度的。
[/Quote]


create or replace function NewFormatName(orderid in orderhist.orderid%type)
return varchar2 is returnProName varchar2(1500);
v_proName varchar2(100);
v_num number(10);
v_result varchar2(400);
cursor c_proName is
select decode(od.prodname,'','',od.prodname) || '*' from orderdet od,orderhist oh where od.orderid=oh.orderid;
begin
open c_proName;
loop
fetch c_proName into v_result;
exit when c_proName%notfound;
returnProName:=returnProName ||' ' || v_result;
dbms_output.put_line(returnProName);
end loop;
close c_proName;
return (returnProName);
end NewFormatName;
数据有点多,加了 dbms_output.put_line(returnProName);
PL/SQL 快挂了
inthirties 2009-06-29
  • 打赏
  • 举报
回复
那现在还出错没有。
zkvistor 2009-06-29
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 inthirties 的回复:]


那有可能是returnProName超过了定义的长度了。你可以把 dbms_output.put_line(returnProName); 拿走,加个判断,就是大于1500(定义的长度)才打出来信息。看有没有这条信息打出来。
[/Quote]

加了,没有任何信息
inthirties 2009-06-29
  • 打赏
  • 举报
回复


那有可能是returnProName超过了定义的长度了。你可以把 dbms_output.put_line(returnProName); 拿走,加个判断,就是大于1500(定义的长度)才打出来信息。看有没有这条信息打出来。
suncrafted 2009-06-29
  • 打赏
  • 举报
回复
帮顶了
zkvistor 2009-06-27
  • 打赏
  • 举报
回复

create or replace function NewFormatName(orderid in orderhist.orderid%type)
return varchar2 is returnProName varchar2(1500);
v_proName varchar2(100);
v_num number(10);
v_result varchar2(400);
cursor c_proName is
select decode(od.prodname,'','',od.prodname) || '*' from orderdet od,orderhist oh where od.orderid=oh.orderid;
begin
open c_proName;
loop
fetch c_proName into v_result;
exit when c_proName%notfound;
returnProName:=returnProName ||' ' || v_result;
end loop;
close c_proName;
return (returnProName);
end NewFormatName;

但是执行的时候报错:数字或值错误 指向 returnProName:=returnProName ||' ' || v_result;
这一行
zkvistor 2009-06-27
  • 打赏
  • 举报
回复
no body?
inthirties 2009-06-27
  • 打赏
  • 举报
回复
引用 6 楼 inthirties 的回复:

指向returnProName:=returnProName ||' ' || v_result;这一行

可能是指向returnProName的长度已经超过了定义的长度了。


你可以在循环里output一下returnProName的长度,看是循环到什么时候操过长度的。
welyngj 2009-06-27
  • 打赏
  • 举报
回复
给一个表定义吧

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧