用存储过程插入blob字段的问题。

时间:2022-04-20 14:00:25
我用qt连接数据库oracle 10g,第一次直接在存储过程直接插入blob字段,只有几百字节的图片才能插入成功,然后我在存储过程里改为先插入empty_blob(),然后update,但是还是只能插入10来kB的图片,求解。

8 个解决方案

#1


--给个例子,在10g下调试通过
CREATE TABLE IMAGE_LOB (T_ID VARCHAR2 (5) NOT NULL,T_IMAGE BLOB NOT NULL); 
CREATE OR REPLACE DIRECTORY IMAGES AS 'd:\temp\pic'; 
 
CREATE OR REPLACE PROCEDURE IMG_INSERT(TID VARCHAR2, FILENAME VARCHAR2) AS
  F_LOB BFILE; --文件类型
  B_LOB BLOB;
BEGIN
  INSERT INTO IMAGE_LOB
    (T_ID, T_IMAGE)
  VALUES
    (TID, EMPTY_BLOB()) RETURN T_IMAGE INTO B_LOB;
  --插入空的blob
  F_LOB := BFILENAME('IMAGES', FILENAME);
  --获取指定目录下的文件
  DBMS_LOB.FILEOPEN(F_LOB, DBMS_LOB.FILE_READONLY);
  --以只读的方式打开文件
  DBMS_LOB.LOADFROMFILE(B_LOB, F_LOB, DBMS_LOB.GETLENGTH(F_LOB));
  --传递对象
  DBMS_LOB.FILECLOSE(F_LOB);
  --关闭原始文件
  COMMIT;
END;

EXEC IMG_INSERT('1','1.gif');

#2


学习~~~~~~~~~~~~~~

#3


引用 1 楼 tangren 的回复:
SQL code
--给个例子,在10g下调试通过
CREATE TABLE IMAGE_LOB (T_ID VARCHAR2 (5) NOT NULL,T_IMAGE BLOB NOT NULL); 
CREATE OR REPLACE DIRECTORY IMAGES AS 'd:\temp\pic'; 
 
CREATE OR REPLACE PROCEDURE IMG_INSERT(T……

谢谢,但是这样子不是只能读取d:\temp\pic吗?有没有什么办法读取任何路径的图片?

#4


oracle数据库如果要访问磁盘文件,必须创建目录,并进行授权,
防止非法操作操作系统数据文件,oracle主要是从安全上考虑的。

#5


再传入一个变量啊 ,这个变量就是 图片路径啊,然后就可以随便取路径了

#6



declare
  v_path  varchar2(4000);
  v_sql  varchar2(4000);
begin
  
  v_path := '''d:\temp\pic''';

  v_sql := 'create or replace directory IMAGES_bak  as '||v_path;
  
  execute immediate v_sql;
  
  
end;

#7


引用 4 楼 tangren 的回复:
oracle数据库如果要访问磁盘文件,必须创建目录,并进行授权,
防止非法操作操作系统数据文件,oracle主要是从安全上考虑的。

那能不能直接传blob字段过去吧,访问磁盘文件由c++来做,我原来是这样写的。
create or replace procedure proInsertEmployee(
P_EmployJoinData varchar2,/*加入部门时间*/
P_EmployeeName varchar2 ,/*姓名*/
P_DepartmentNo char,/*所属部门*/
P_sex char,/*性别*/
P_EmployeeDate date,/*出生日期*/
P_WorkDate date,/*工作日期*/
P_NationNo char ,/*民族*/
P_PostNo char,/*岗位*/
P_EmployeeMemo varchar2,/*简历*/
P_EmployeeImage varchar2/*照片*/


)as
 employ_No varchar(8);
begin
  --产生主键号
   employ_No:=funemployeeno(P_EmployJoinData);
   insert into Employee(EmployeeNo,EmployeeName,DepartmentNo,
   sex,EmployeeDate,WorkDate,NationNo,PostNo) values(employ_No,
   P_EmployeeName,P_DepartmentNo, P_sex,
   P_EmployeeDate,P_WorkDate,P_NationNo,P_PostNo);
   insert into EmployeeOther values(employ_No,P_EmployeeMemo,empty_blob());
   update EmployeeOther set EmployeeImage = P_EmployeeImage where employeeno = employ_No;
   exception
     when others then
      rollback;
   commit;
end proInsertEmployee;

#8


上面的P_EmployeeImage是blob类型的,刚才改了varchar2类型,忘了改回来了。

#1


--给个例子,在10g下调试通过
CREATE TABLE IMAGE_LOB (T_ID VARCHAR2 (5) NOT NULL,T_IMAGE BLOB NOT NULL); 
CREATE OR REPLACE DIRECTORY IMAGES AS 'd:\temp\pic'; 
 
CREATE OR REPLACE PROCEDURE IMG_INSERT(TID VARCHAR2, FILENAME VARCHAR2) AS
  F_LOB BFILE; --文件类型
  B_LOB BLOB;
BEGIN
  INSERT INTO IMAGE_LOB
    (T_ID, T_IMAGE)
  VALUES
    (TID, EMPTY_BLOB()) RETURN T_IMAGE INTO B_LOB;
  --插入空的blob
  F_LOB := BFILENAME('IMAGES', FILENAME);
  --获取指定目录下的文件
  DBMS_LOB.FILEOPEN(F_LOB, DBMS_LOB.FILE_READONLY);
  --以只读的方式打开文件
  DBMS_LOB.LOADFROMFILE(B_LOB, F_LOB, DBMS_LOB.GETLENGTH(F_LOB));
  --传递对象
  DBMS_LOB.FILECLOSE(F_LOB);
  --关闭原始文件
  COMMIT;
END;

EXEC IMG_INSERT('1','1.gif');

#2


学习~~~~~~~~~~~~~~

#3


引用 1 楼 tangren 的回复:
SQL code
--给个例子,在10g下调试通过
CREATE TABLE IMAGE_LOB (T_ID VARCHAR2 (5) NOT NULL,T_IMAGE BLOB NOT NULL); 
CREATE OR REPLACE DIRECTORY IMAGES AS 'd:\temp\pic'; 
 
CREATE OR REPLACE PROCEDURE IMG_INSERT(T……

谢谢,但是这样子不是只能读取d:\temp\pic吗?有没有什么办法读取任何路径的图片?

#4


oracle数据库如果要访问磁盘文件,必须创建目录,并进行授权,
防止非法操作操作系统数据文件,oracle主要是从安全上考虑的。

#5


再传入一个变量啊 ,这个变量就是 图片路径啊,然后就可以随便取路径了

#6



declare
  v_path  varchar2(4000);
  v_sql  varchar2(4000);
begin
  
  v_path := '''d:\temp\pic''';

  v_sql := 'create or replace directory IMAGES_bak  as '||v_path;
  
  execute immediate v_sql;
  
  
end;

#7


引用 4 楼 tangren 的回复:
oracle数据库如果要访问磁盘文件,必须创建目录,并进行授权,
防止非法操作操作系统数据文件,oracle主要是从安全上考虑的。

那能不能直接传blob字段过去吧,访问磁盘文件由c++来做,我原来是这样写的。
create or replace procedure proInsertEmployee(
P_EmployJoinData varchar2,/*加入部门时间*/
P_EmployeeName varchar2 ,/*姓名*/
P_DepartmentNo char,/*所属部门*/
P_sex char,/*性别*/
P_EmployeeDate date,/*出生日期*/
P_WorkDate date,/*工作日期*/
P_NationNo char ,/*民族*/
P_PostNo char,/*岗位*/
P_EmployeeMemo varchar2,/*简历*/
P_EmployeeImage varchar2/*照片*/


)as
 employ_No varchar(8);
begin
  --产生主键号
   employ_No:=funemployeeno(P_EmployJoinData);
   insert into Employee(EmployeeNo,EmployeeName,DepartmentNo,
   sex,EmployeeDate,WorkDate,NationNo,PostNo) values(employ_No,
   P_EmployeeName,P_DepartmentNo, P_sex,
   P_EmployeeDate,P_WorkDate,P_NationNo,P_PostNo);
   insert into EmployeeOther values(employ_No,P_EmployeeMemo,empty_blob());
   update EmployeeOther set EmployeeImage = P_EmployeeImage where employeeno = employ_No;
   exception
     when others then
      rollback;
   commit;
end proInsertEmployee;

#8


上面的P_EmployeeImage是blob类型的,刚才改了varchar2类型,忘了改回来了。