蒙在股里 发表于 2015-1-16 22:38:54

MYSQL网站制作之在Oracle 8i的SQL*Plus中怎样使用LOB字...

WindowsAzureSQLDatabase并不支持数据压缩和表分区之类的功能,而且SQLDatabase支持的Transact-SQL语言只是完整版的一部分。另外,因为解决方案提供商不能控制物理资源,所以他们不能将数据文件和索引分配给特定的硬件。oracle|二进制
在Oracle8i的SQL*Plus中怎样使用LOB字段存取操纵体系二进制文件


广东省岭澳核电无限公司工程把持处办理信息科(518124)黄福同


Oracle8i数据库体系功效比后面版本加倍完美,特别是呈现了BLOB,CLOB,NCLOB,
BFILE这些LOB(年夜型工具)范例来代替功效无限的LONG、LONGRAW范例。BLOB字段最
年夜长度为4G(4,294,967,295)字节,并且不再象LONGRAW那样每一个表中只是限定有一
个字段是LONGRAW(最长2G)型的。BLOB,CLOB,NCLOB为外部BLOB(数据一般在数据
库中寄存),BFILE为内部LOB(所存储的只是指向内部操纵体系文件的指针),用户可
以利用PL/SQL的包DBMS_LOB来处置LOB数据,可是遗憾的是,DBMS_LOB包只能将二进
制操纵体系文件写进到BLOB字段中,却没法将BLOB字段中的二进制操纵体系文件取回
到操纵体系中,估量未来会有所改良。本文迁就怎样在SQL*Plus将WORD文件存进掏出
ORACLE中作具体注释申明,供列位偕行参考。

实行的软件情况以下:Windows2000AdvancedServer,Oracle8.1.7,VC++6.0+SP5
硬件情况以下:双PIII866CPU,768M内存

在internal这个用户下给scott用户受权以下:
SQL>grantcreateanydirectorytoscott;
SQL>grantcreateanylibrarytoscott;
在scott这个用户下实行下述语句:

SQL>createtablebfile_tab(bfile_columnBFILE);
SQL>createtableutl_lob_test(blob_columnBLOB);
SQL>createorreplacedirectoryutllobdirasC:DDSEXTPROC;
SQL>setserveroutputon

然后实行上面语句就将C:DDSEXTPROC目次下的word文件COM.doc存进到utl_lob_test
表中的blob_column字段中了。

declare
a_blobBLOB;
a_bfileBFILE:=BFILENAME(UTLLOBDIR,COM.doc);--用来指向内部操纵体系

文件
begin
insertintobfile_tabvalues(a_bfile)
returningbfile_columnintoa_bfile;
insertintoutl_lob_testvalues(empty_blob())
returningblob_columnintoa_blob;
dbms_lob.fileopen(a_bfile);
dbms_lob.loadfromfile(a_blob,a_bfile,dbms_lob.getlength(a_bfile));
dbms_lob.fileclose(a_bfile);
commit;
end;
/
SQL>showerrors
此时可使用DBMS_LOB包的getlength这个procedure来检测是不是已将该word文件存进
到blob字段中了。如:
SQL>selectdbms_lob.getlength(blob_column)fromUTL_LOB_TEST;
了局以下:
DBMS_LOB.GETLENGTH(BLOB_COLUMN)
-------------------------------
83968
申明该word文件已存进到blob字段中往了。

上面迁就怎样掏出该word文件到操纵体系下作具体注释:
Oracle8.1.7只能用pro*c与OCI来完成该义务,以是Oracle服务器端必需撑持pro*c
和内部library,Oracle8.1.7数据库默许安装为撑持pro*c和内部Procedure,
用户能够本人反省一下listener.ora和tnsnames.ora这两个文件。
listener.ora中包括以下语句:
SID_LIST_LISTENER=
(SID_LIST=
(SID_DESC=
(SID_NAME=PLSExtProc)
(ORACLE_HOME=D:oracleora81)
(PROGRAM=extproc)
)
(SID_DESC=
(GLOBAL_DBNAME=hft)
(ORACLE_HOME=D:oracleora81)
(SID_NAME=hft)
)
)
tnsnames.ora中包括以下语句:
EXTPROC_CONNECTION_DATA=
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC0))
)
(CONNECT_DATA=
(SID=PLSExtProc)
(PRESENTATION=RO)
)
)

上面这个文件为lob2file.c,详细感化是将BLOB中的二进制文件倒出到操纵体系中。
/*beginoflob2file.c*/
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<oci.h>
#include<ociextp.h>
#defineDEFAULT_CHUNK_SIZE1024
staticintlogging;
staticcharlogfile;
staticFILE*logfilep=NULL;
intlob2file(OCILobLocator*a_lob,/*theLOB*/
shortlbind,/*LOBindicator*/
char*path,/*filetowrite*/
shortpind,/*fileindicator*/
intplen,/*filenamelength*/
char*lpath,/*logfilename*/
shortlpind,/*logfileindicator*/
intlplen,/*logfilenamelength*/
intlogit,/*loggingenabled?*/
OCIExtProcContext*ctxt/*OCIContext*/
)
{
sworderrnum=0;
OCIEnv*envhp=NULL;
OCISvcCtx*svchp=NULL;
OCIError*errhp=NULL;
charlobfile;
FILE*lobfilep=NULL;
/*
*Ifrequired,openthelogfileforwriting
*Usetheuserprovidedlogfilenameifpossible
*Otherwise,defaultthelogfiletolob2file.log
*/
logging=logit;
if(logging)
{
if(lpind==-1||lplen==0||lplen>=512)
{
strcpy(logfile,"lob2file.log");
}
else
{
strncpy(logfile,lpath,lplen);
logfile=;
}
logfilep=fopen(logfile,"w");
if(logfilep==NULL)
{
if((logfilep=fopen("lob2file.log","w"))!=NULL)
{
fprintf(logfilep,"Error:Unabletoopenlogfile%s
",

logfile);
fprintf(logfilep,"Error:errno=%d
",errno);
}
}
}
/*
*Retrievetheenvironment,servicecontext,anderrorhandles
*/
if((errnum=OCIExtProcGetEnv(ctxt,&envhp,
&svchp,&errhp))!=OCIEXTPROC_SUCCESS)
{
if(logging&&logfilep!=NULL)
{
fprintf(logfilep,"Error:CalltoOCIExtProcGetEnvfailed
");
fprintf(logfilep,"Error:OCIExtProcGetEnvreturned%d
",

errnum);
fclose(logfilep);
return-1;
}
}
/*
*Verifythattheuserhasprovidedanamefortheoutputfile
*/
if(pind==-1||plen==0)
{
char*errmsg="Pathnameisnulloremptystring";
if(logging&&logfilep!=NULL)
{
fprintf(logfilep,"Error:%s
",errmsg);
fclose(logfilep);
}
errnum=20001;
OCIExtProcRaiseExcpWithMsg(ctxt,errnum,(text*)errmsg,

strlen(errmsg));
return-1;
}
else/*Usetheprovidedname*/
{
strncpy(lobfile,path,plen);
lobfile=;
}
/*
*VerifythattheuserhasprovidedavalidLOBlocator
*/
if(lbind==-1)
{
char*errmsg="LOBlocatorisnull";
if(logging&&logfilep!=NULL)
{
fprintf(logfilep,"Error:%s
",errmsg);
fclose(logfilep);
}
errnum=20002;
OCIExtProcRaiseExcpWithMsg(ctxt,errnum,(text*)errmsg,

strlen(errmsg));
return-1;
}
if(logging&&logfilep!=NULL)
fprintf(logfilep,"OpeningOSfileinwritemode
");
/*
*Opentheoutputfileforwriting
*/
if((lobfilep=fopen(lobfile,"wb"))!=NULL)
{
dvoid*chunk;
ub4cksz=0,totsz=0;
if(logging&&logfilep!=NULL)
fprintf(logfilep,"GettingtotalsizeforLOB
");
if(checkerr(ctxt,errhp,
OCILobGetLength(svchp,errhp,a_lob,&totsz))!=0)
return-1;
/*
*For8.0.XtheOCILogGetChunkSizewillnothavebeencalled.
*INthiscase,resetthechunksizeto1K.
*/
if(cksz==0)cksz=DEFAULT_CHUNK_SIZE;
if(logging&&logfilep!=NULL)
fprintf(logfilep,
"Allocating%dbytesofmemoryforLOBchunks
",
(int)cksz);
/*
*Dynamicallyallocateenoughmemorytoholdasinglechunk
*/
if((chunk=OCIExtProcAllocCallMemory(ctxt,(size_t)cksz))!=NULL)
{
intcnt=1;
ub4amt=cksz,offset=1;
/*
*ReaddatafromtheLOBandwriteittothefilewhile
*moredataremains.
*/
while(offset<(int)totsz)
{
if(logging&&logfilep!=NULL)
fprintf(logfilep,
"Readingchunk%dstartingat%dformax%d

bytes
",
cnt,(int)offset,(int)amt);
errnum=OCILobRead(svchp,errhp,a_lob,&amt,offset,
chunk,cksz,(dvoid*)0,
(sb4(*)(dvoid*,dvoid*,ub4,ub1))0,
(ub2)0,(ub1)SQLCS_IMPLICIT);
if(checkerr(ctxt,errhp,errnum)!=0)return-1;
if(logging&&logfilep!=NULL)
fprintf(logfilep,
"Successfullyreadchunkcontaining%dbytes
",
(int)amt);
if(logging&&logfilep!=NULL)
fprintf(logfilep,
"Writing%dbytesofchunk%dtofile%s
",
(int)amt,cnt,lobfile);
if(fwrite((void*)chunk,(size_t)1,(size_t)amt,lobfilep)==

amt)
{
if(logging&&logfilep!=NULL)
fprintf(logfilep,"Successfullywrote%dbytestofile

%s
",
(int)amt,lobfile);
}
else
{
char*errmsg="WritetoOSfilefailed";
if(logging&&logfilep!=NULL)
{
fprintf(logfilep,"Error:%s
",errmsg);
fprintf(logfilep,"Error:errno=%d
",errno);
}
errnum=20003;
OCIExtProcRaiseExcpWithMsg(ctxt,errnum,
(text*)errmsg,strlen(errmsg));
return-1;
}
cnt++;
offset+=amt;
}
if(logfilep!=NULL)fclose(logfilep);
fclose(lobfilep);
return0;
}
else
{
if(logging&&logfilep!=NULL)
{
fprintf(logfilep,"Error:Unabletoallocatememory
");
fclose(logfilep);
}
return-1;
}
}
else
{
char*errmsg="Unabletoopenfile";
if(logging&&logfilep!=NULL)
{
fprintf(logfilep,"Error:%s%s
",errmsg,lobfile);
fprintf(logfilep,"Error:errno=%d
",errno);
fclose(logfilep);
}
errnum=20003;
OCIExtProcRaiseExcpWithMsg(ctxt,errnum,
(text*)errmsg,strlen(errmsg));
return-1;
}
}

intcheckerr(OCIExtProcContext*ctxt,OCIError*errhp,swordstatus)
{
sworderrnum=0;
texterrbuf;
switch(status)
{
caseOCI_SUCCESS_WITH_INFO:
errnum=20004;
strcpy((char*)errbuf,"Error:OCI_SUCCESS_WITH_INFO");
break;
caseOCI_NO_DATA:
errnum=20005;
strcpy((char*)errbuf,"Error:OCI_NO_DATA");
break;
caseOCI_NEED_DATA:
errnum=20006;
strcpy((char*)errbuf,"Error:OCI_NEED_DATA");
break;
caseOCI_INVALID_HANDLE:
errnum=20007;
strcpy((char*)errbuf,"Error:OCI_INVALID_HANDLE");
break;
caseOCI_STILL_EXECUTING:
errnum=20008;
strcpy((char*)errbuf,"Error:OCI_STILL_EXECUTING");
break;
caseOCI_CONTINUE:
errnum=20009;
strcpy((char*)errbuf,"Error:OCI_CONTINUE");
break;
caseOCI_ERROR:
(void)OCIErrorGet((dvoid*)errhp,(ub4)1,(text*)NULL,
(sb4*)&errnum,(text*)errbuf,
(ub4)sizeof(errbuf),OCI_HTYPE_ERROR);
break;
default:
break;
}
if(errnum!=0)
{
if(logging&&logfilep!=NULL)
{
fprintf(logfilep,"Error:%d%s
",errnum,errbuf);
fclose(logfilep);
}
(void)OCIExtProcRaiseExcpWithMsg(ctxt,errnum,errbuf,

strlen(errbuf));
}
returnerrnum;
}
/*endoffilelob2file.c*/

将文件lob2file.c放到D:oracleora81plsqldemo目次下:然后在dos下实行下述编


语句将该文件编译成lob2file.dll文件,make.bat文件包括以下:

@echooff
cl-ID:oracleora81ociinclude-D_DLL-D_MT/LD-Zilob2file.c/link
D:oracleora81ocilibmsvcoci.libmsvcrt.lib/nod:libcmt/DLL
/EXPORT:lob2file/EXPORT:checkerr

进进D:oracleora81plsqldemo目次(DOS形态)实行make就能够将lob2file.c编
译成lob2file.dll文件了。

然后用scott连到sql*plus中,实行
SQL>CREATEORREPLACELIBRARYUTLLOBLIB
ASD:oracleora81plsqldemolob2file.dll
/
SQL>GRANTEXECUTEONUTLLOBLIBTOPUBLIC

然后实行下述代码:
createorreplacepackageutl_lobis
procedureSetLogging(whichBOOLEAN,a_logVARCHAR2);
procedureUnloadToFile(a_lobBLOB,a_fileVARCHAR2,statusOUTNUMBER);
endutl_lob;
/
showerrors
createorreplacepackagebodyutl_lobis
logSettingBOOLEAN:=FALSE;
logFileNameVARCHAR2(512):=NULL;
procedureSetLogging(whichBOOLEAN,a_logVARCHAR2)is
begin
logSetting:=which;
if(logSetting=TRUE)then
logFileName:=a_log;
else
logFileName:=NULL;
endif;
end;

functionLobToFile(a_lobBLOB,a_fileVARCHAR2,a_logVARCHAR2,logging

BOOLEAN)
returnBINARY_INTEGERasexternal
name"lob2file"
libraryutlloblib
LANGUAGEC
withcontext
parameters(a_lobOCILOBLOCATOR,
a_lobINDICATORSHORT,
a_fileSTRING,
a_fileINDICATORSHORT,
a_fileLENGTHINT,
a_logSTRING,
a_logINDICATORSHORT,
a_logLENGTHINT,
loggingINT,
CONTEXT,
RETURN);
procedureUnloadToFile(a_lobBLOB,a_fileVARCHAR2,statusOUTNUMBER)is
begin
status:=LobToFile(a_lob,a_file,logFileName,logSetting);
end;
endutl_lob;
/
showerrors
grantexecuteonutl_lobtopublic;

该代码创立packageutl_lob,而utl_lob挪用libraryutlloblib,我们的测试程序调


packageutl_lob中的procedureSetLogging和UnloadToFile。在scott用户下实行以下
剧本,就能够将先前保留的COM.doc掏出放到C:DDSEXTPROC        est.doc这个文件中,当


C:DDSEXTPROC这个目次必需存在。剧本实行终了后天生两个文件test.log与test.doc


test.log记录了掏出的具体信息,test.doc是COM.doc的复成品,掏出82K巨细的文件年夜

约用了4秒。

--以下为测试剧本
setserveroutputon
declare
a_blobBLOB;
statusNUMBER;
begin
selectblob_columnintoa_blobfromutl_lob_test;
utl_lob.SetLogging(TRUE,C:DDSEXTPROC        est.log);
utl_lob.UnloadToFile(a_blob,C:DDSEXTPROC        est.doc,status);
dbms_output.put_line(Exitstatus=||status);
end;
/
人人对下面测试剧本略微修改一下,构成一个带参数的Procedure供给用程序挪用便可

以了。


DBaaS和其他云服务之间的区别是:DBaaS专注于提供类似关系数据库管理系统RDBMS(比如SQLServer、MySQL和Oracle)的数据库功能。事实上,RDBMS已被证明是一种适合于在各种情况下管理结构化数据的有效工具。

再见西城 发表于 2015-1-19 20:26:41

在select语句中可以使用groupby子句将行划分成较小的组,然后,使用聚组函数返回每一个组的汇总信息,另外,可以使用having子句限制返回的结果集。

若天明 发表于 2015-1-27 05:32:16

理解了存储结构,再阅读下性能优化的章节基本上会对sqlserver有个清晰地认识

透明 发表于 2015-2-5 00:10:13

比如,MicrosoftSQLServer2008的某一个版本可以满足现在的这个业务的需要,而且价格还比Oracle11g要便宜,那么这一产品就是适合的。

小女巫 发表于 2015-2-10 23:47:06

财务软件要用SQL也只是后台的数据库而已,软件都是成品的,当然多学东西肯定是有好处的..

柔情似水 发表于 2015-3-1 18:05:27

换言之,只有在不断的失败中尝试成功,而关于失败的总结却是很少的

不帅 发表于 2015-3-10 21:40:45

另一个是把SQL语句写到服务器端,就是所谓的SP(存储过程);

分手快乐 发表于 2015-3-17 10:46:34

微软对CLR作了大篇幅的宣传,这是因为数据库产品终于融入.net体系中。最开始我们也是狂喜,感觉对象数据库的一些概念可以实现了。

再现理想 发表于 2015-3-24 07:42:47

对递归类的树遍历很有帮助。个人感觉这个真是太棒了!阅读清晰,非常有时代感。
页: [1]
查看完整版本: MYSQL网站制作之在Oracle 8i的SQL*Plus中怎样使用LOB字...