急!在线等!!!Oracle的存储过程 (100分)

  • 主题发起人 主题发起人 erbird
  • 开始时间 开始时间
E

erbird

Unregistered / Unconfirmed
GUEST, unregistred user!
我建了两个表:
--业务信息表
Create Sequence InfoID
Start With 1
Increment By 1;

CREATE TABLE YW_Info(
InfoID number PRIMARY KEY, --信息ID
AcceptNum varchar(14) NOT NULL Unique, --受理编号
PhoneCode varchar(8) NOT NULL, --电话号码
Client varchar(40), --客户名称
FormerClient varchar(40), --原客户名称
Account varchar(20), --用户帐号名
IDCard varchar(18), --身份证号
RegisterDate date, --登记日期
FinishDate date, --竣工日期
InstallAddr varchar(40), --装机地址
PicID number DEFAULT 0); --图片库的ID

--图片表
Create Sequence PicID
Start With 1
Increment By 1;

CREATE TABLE YW_Pic(
PicID number PRIMARY KEY, --图片ID
PicInfo blob NOT NULL); --图片信息
现在我要建一个存储过程,功能是:在图片库YW_Pic中加入图片后自动产生PicID,然后使图片表YW_Pic的PicID对应业务信息表YW_Info中的PicID。原来用SQL Server中这样写:
--添加图片
DROP PROC PM_ApendPicProc
GO
CREATE PROC PM_ApendPicProc @iInfoID bigint,@sImage image
AS
INSERT INTO YW_Pic(PicInfo) VALUES (@sImage)
UPDATE YW_Info
SET PicID=@@IDENTITY
WHERE InfoID=@iInfoID
GO
现我要用oracle改写,为:
CREATE OR REPLACE PROCEDURE PM_ApendPicProc
(iInfoID number,sImage Blob)
AS
BEGIN
INSERT INTO YW_Pic(PicInfo) VALUES (sImage);
UPDATE YW_Info
SET PicID=IDENTITY
WHERE InfoID=iInfoID;
END;
/
在SQL Server中能直接插入已经转为二进制的图片,在oracle中好像不行,我该怎么写???
代码:
 
ORACLE中不能通过输入参数为BLOB类型来将值传进存储过程中。
必须要使用dbms_lob包。或者是使用DELPHI中的TBlobField。

另外,ORACLE中的SEQUENCE与SQL SERVER中的自增型变量用法不同。

1 创建SEQUENCE
2 select seqname.nextval from dual;
3 在insert之前,执行2的操作,将值取出,然后在insert时显式地写出字段值。

identify是啥东东?不好意思,SQL SERVER我不太清楚。
 
在SQL SERVER中InfoID int IDENTITY(1,1)就是InfoID从1开始自动递增1,
SET PicID=@@IDENTITY的意思是让两个表的PicID一一对应。oracle我才用了两个星期,
--ORACLE中不能通过输入参数为BLOB类型来将值传进存储过程中。必须要使用dbms_lob包。
你能不能说得具体些,最好有代码。
 
将文件名作为参数传给数据库的存储过程,在存储过程中使用dbms_lob.loadfromfile()
将内容从文件中加载到数据库。
具体用delphi来写的话,你的目标我可能会改写为两层:
1 插入YW_PIC
with tabYW_PIC do
begin
edit;
Insert;
(fieldbyname('PICINFO') as tblobfield).loadfromfile(filename);
Post;
end;
2 建立trigger完成两张数据表的相关字段的匹配
CREATE OR REPLACE TRIGGER tri_ins_ywpic
BEFORE INSERT ON yw_pic
REFERENCING
NEW AS NEW
OLD AS OLD
FOR EACH ROW
begin
select seq.nextval into :new.picid from dual;
end;

前面只写了YW_PIC的有关操作,结合你的YW_INFO,需要增强代码内容。
 
建表的时候我已经建立了触发器让表的ID自动递增,运行成功:
CREATE OR REPLACE TRIGGER YW_Pic_RIGGER
BEFORE INSERT
ON YW_Pic FOR EACH ROW
BEGIN
SELECT SePicID.NEXTVAL INTO :NEW.PicID FROM DUAL;
END;
/
我这样做是不是已经把两个表的PicID一一对应上了?因为在SQL Server中得加一条语句
SET PicID=@@IDENTITY。我现在是在存储过程中插不进blob,看了一些资料说在oracle中不能
直接插入blob,如果用long raw有没有大小问题,我要存150k一张的图片?还有,在delphi
里我用的是ADOStoredProc控件,是这样写的:
if dmMain.spAppendPic.Active=True then
dmMain.spAppendPic.Active:=False;
dmMain.spAppendPic.Parameters.ParamByName('@iInfoID').Value
:=dmMain.spInputPhoneInfoID.AsInteger;
dmMain.spAppendPic.Parameters.ParamByName('@sImage').LoadFromFile
(tmpFileName,ftBlob);
这个技术我是源用李维ADO那本书109页,不知你看了吗。其中spAppendPic为ADOStoredProc
控件名。
 
我没有仔细看过李维的那本书!因为我现在所作的编程工作已经很少。
long raw在oracle的高版本中已经被BLOB取代了。
前面所写的trigger只是保证了序列的应用,两个表的关联还需要使用SQL语句来完成。
 
我现在是要用SQL语句在oracle中直接插入图片,
INSERT INTO YW_Pic(PicInfo) VALUES (sImage);
但是oracle不能直接插入,好像有一个转换的函数,请问
是哪个函数???
 
在插入记录时先得有一个empty_lob的动作,然后再需要哪个函数去将内容写入数据库就
不清楚了,因为这种操作数据库所认的是服务器端的一些环境变量,所以我在应用中没有
这样使用过,而是在客户端将内容直接写到数据库里。
 
long raw仍然还是可用的,如果是blob,虽然他在服务器端比较先进,
但是客户端会麻烦一点,ado使用ms的provider、比较低版的odac、以及bde问题都不小,
而long raw则各个客户端都支持得很好
至于知道insert的id值,oracle是这样做的:
定义一个变量 pid 的话:
INSERT INTO YW_Pic(PicInfo) VALUES (sImage) returning PicID into pid;
然后pid就是你刚刚insert的那行数据的PicID的值,可以用在后面的update命令
 
各位,现在我已经能正确的插入图片了。
Pipi:
我的意思你已经明白了,请问是这样写吗?
CREATE OR REPLACE PROCEDURE PM_ApendPicProc
(iInfoID number,sImage IN OUT long raw,Pid number)
AS
BEGIN
INSERT INTO YW_Pic(PicInfo) VALUES (sImage) return PicID into Pid;
UPDATE YW_Info
SET PicID=Pid
WHERE InfoID=iInfoID;
END;
/
提示错误:
5/3 PL/SQL: SQL Statement ignored
5/65 PLS-00403: 表达式 'PID' 不能作为 SELECT/FETCH 语句的 INTO 目标
请问怎么写???ruturn改为ruturning也不行。
 
pid不能象你那样使用!

CREATE OR REPLACE PROCEDURE PM_ApendPicProc
(iInfoID in number,sImage IN long raw)
is
pid integer;
BEGIN
INSERT INTO YW_Pic(PicInfo) VALUES (sImage) returning PicID into Pid;
......
END;
/

取值到pid中的动作经过测试!
 
sorry !no time to answer it !
 
是的pid作为本地变量
如果你想作为参数返回,按你原来的写法,需要把参数定义为 in out 类型才可以
另外,不是return……into,而是returning……into, 注意 ing
 
真的谢谢armyjiang和Pipi,我刚用oracle两个多星期,所以有很多不懂的地方。
现在编译成功了但是我的sImage 只能定义为 in long raw,而不是in out long raw,否则
在delphi里调用的时候报错:Parameter对象被不正确的定义。提供了不一致或不完整的
信息。这是为什么??下面是我的程序:
CREATE OR REPLACE PROCEDURE PM_ApendPicProc
(iInfoID in number,sImage IN long raw)
AS
Pid:integer;
BEGIN
INSERT INTO YW_Pic(PicInfo) VALUES (sImage) returning PicID into Pid;
UPDATE YW_Info
SET PicID=Pid
WHERE InfoID=iInfoID;
END;
/

结帖了。
 
后退
顶部