明朝与清朝对比:VC文件格式

来源:百度文库 编辑:偶看新闻 时间:2024/04/20 01:47:12

VC文件格式

作者 fevair 18:11 | 静态链接网址 | 最新回复 (0) | 引用 (0) | C++/VC

.opt 工程关于开发环境的参数文件。如工具条位置等信息;
.aps (AppStudio File),
资源辅助文件,二进制格式,一般不用去管他
.
.clw ClassWizard
信息文件,实际上是INI文件的格式,有兴趣可以研究一下.有时候ClassWizard出问题,手工修改CLW文件可以解决.如果此文件不存在的话,每次用ClassWizard的时候绘提示你是否重建
.
.dsp (DeveloperStudio Project):
项目文件,文本格式,不过不熟悉的话不要手工修改

.dsw(DeveloperStudio Workspace)
是工作区文件,其他特点和DSP差不多
.
.plg
是编译信息文件,编译时的errorwarning信息文件(实际上是一个html文件),一般用处不大.Tools->Options里面有个选项可以控制这个文件的生成
.
.hpj (Help Project)
是生成帮助文件的工程,microsfot Help Compiler可以处理
.
.mdp (Microsoft DevStudio Project)
是旧版本的项目文件,如果要打开此文件的话,会提示你是否转换成新的DSP格式
.
.bsc
是用于浏览项目信息的,如果用Source Brower的话就必须有这个文件.如果不用这个功能的话,可以在Project Options里面去掉Generate Browse Info File,可以加快编译速度
.
.map
是执行文件的映像信息纪录文件,除非对系统底层非常熟悉,这个文件一般用不着
.
.pch (Pre-Compiled File)
是预编译文件,可以加快编译速度,但是文件非常大
.
.pdb (Program Database)
记录了程序有关的一些数据和调试信息,在调试的时候可能有用
.
.exp
只有在编译DLL的时候才会生成,记录了DLL文件中的一些信息.一般也没什么用. +.ncb 无编译浏览文件(no compile browser)。当自动完成功能出问题时可以删除此文件。build后会自动生成。

备份文件时,不必须的文件都可以删除(尤其是ncb,opt,pch,这些文件常常很大)。


23 09, 2006

LNK2001错误探究[]

作者 fevair 18:10 | 静态链接网址 | 最新回复 (0) | 引用 (0) | C++/VC

  学习VC++时经常会遇到链接错误LNK2001,该错误非常讨厌,因为对于编程者来说,最好改的错误莫过于编译错误,而一般说来发生连接错误时,编译都已通过。产生连接错误的原因非常多,尤其LNK2001错误,常常使人不明其所以然。如果不深入地学习和理解VC++,要想改正连接错误LNK2001非常困难。

  初学者在学习VC++的过程中,遇到的LNK2001错误的错误消息主要为:

  unresolved external symbol “symbol”(不确定的外部“符号”)。

  如果连接程序不能在所有的库和目标文件内找到所引用的函数、变量或标签,将产生此错误消息。一般来说,发生错误的原因有两个:一是所引用的函数、变量不存在、拼写不正确或者使用错误;其次可能使用了不同版本的连接库。

  以下是可能产生LNK2001错误的原因:

  一.由于编码错误导致的LNK2001。

  1.不相匹配的程序代码或模块定义(.DEF)文件能导致LNK2001。例如,如果在C++源文件内声明了一变量“var1”,却试图在另一文件内以变量“VAR1”访问该变量,将发生该错误。

  2.如果使用的内联函数是在.CPP文件内定义的,而不是在头文件内定义将导致LNK2001错误。

  3.调用函数时如果所用的参数类型同函数声明时的类型不符将会产生LNK2001。

  4.试图从基类的构造函数或析构函数中调用虚拟函数时将会导致LNK2001。

  5.要注意函数和变量的可公用性,只有全局变量、函数是可公用的。

  静态函数和静态变量具有相同的使用范围限制。当试图从文件外部访问任何没有在该文件内声明的静态变量时将导致编译错误或LNK2001。

  函数内声明的变量(局部变量) 只能在该函数的范围内使用。

  C++的全局常量只有静态连接性能。这不同于C,如果试图在C++的多个文件内使用全局变量也会产生LNK2001错误。一种解决的方法是需要时在头文件中加入该常量的初始化代码,并在.CPP文件中包含该头文件;另一种方法是使用时给该变量赋以常数。

  二.由于编译和链接的设置而造成的LNK2001

  1.如果编译时使用的是/NOD(/NODEFAULTLIB)选项,程序所需要的运行库和MFC库在连接时由编译器写入目标文件模块,但除非在文件中明确包含这些库名,否则这些库不会被链接进工程文件。在这种情况下使用/NOD将导致错误LNK2001。

  2.如果没有为wWinMainCRTStartup设定程序入口,在使用Unicode和MFC时将得到“unresolved external on _WinMain@16”的LNK2001错误信息。

  3.使用/MD选项编译时,既然所有的运行库都被保留在动态链接库之内,源文件中对“func”的引用,在目标文件里即对“_imp__func” 的引用。

  如果试图使用静态库LIBC.LIB或LIBCMT.LIB进行连接,将在__imp__func上发生LNK2001;如果不使用/MD选项编译,在使用MSVCxx.LIB连接时也会发生LNK2001。

  4.使用/ML选项编译时,如用LIBCMT.LIB链接会在_errno上发生LNK2001。

  5.当编译调试版的应用程序时,如果采用发行版模态库进行连接也会产生LNK2001;同样,使用调试版模态库连接发行版应用程序时也会产生相同的问题。

  6.不同版本的库和编译器的混合使用也能产生问题,因为新版的库里可能包含早先的版本没有的符号和说明。

  7.在不同的模块使用内联和非内联的编译选项能够导致LNK2001。如果创建C++库时打开了函数内联(/Ob1或/Ob2),但是在描述该函数的相应头文件里却关闭了函数内联(没有inline关键字),这时将得到该错误信息。为避免该问题的发生,应该在相应的头文件中用inline关键字标志内联函数。

  8.不正确的/SUBSYSTEM或/ENTRY设置也能导致LNK2001。

  其实,产生LNK2001的原因还有很多,以上的原因只是一部分而已,对初学者来说这些就够理解一阵子了。但是,分析错误原因的目的是为了避免错误的发生。LNK2001错误虽然比较困难,但是只要注意到了上述问题,还是能够避免和予以解决的。



23 09, 2006

VC++6.0编译器详解

作者 fevair 18:08 | 静态链接网址 | 最新回复 (0) | 引用 (0) | C++/VC

prettybird 发表于 2005-12-1 15:49:00
大家可能一直在用VC开发软件,但是对于这个编译器却未必很了解。原因是多方面的。大多数情况下,我们只停留在“使用”它,而不会想去“了解”它。因为它只是一个工具,我们宁可把更多的精力放在C++语言和软件设计上。我们习惯于这样一种“模式”:建立一个项目,然后写代码,然后编译,反反复复调试。但是,所谓:“公欲善其事,必先利其器”。如果我们精于VC开发环境,我们是不是能够做得更加游刃有余呢?

  闲话少说。我们先来看一下VC的处理流程,大致分为两步:编译和连接。源文件通过编译生成了.obj文件;所有.obj文件和.lib文件通过连接生成.exe文件或.dll文件。下面,我们分别讨论这两个步骤的一些细节。


  编译参数的设置。主要通过VC的菜单项Project->Settings->C/C++页来完成。我们可以看到这一页的最下面Project Options中的内容,一般如下:

/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_M
BCS" /Fp"Debug/WritingDlgTest.pch" /Yu"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c

  鞲霾问淼囊庖澹梢圆慰糓sdn。比如/nologo表示编译时不在输出窗口显示这些设置(我们可以把这个参数去掉来看看效果)等等。一般我们不会直接修改这些设置,而是通过这一页最上面的Category中的各项来完成。

  1) General:一些总体设置。Warning level用来控制警告信息,其中Level 1是最严重的级别;Warnings as errors将警告信息当作错误处理;Optimizations是代码优化,可以在Category的Optimizations项中进行更细的设置;Generate browse info用以生成.sbr文件,记录类、变量等符号信息,可以在Category的Listing Files项中进行更多的设置。Debug info,生成调试信息:None,不产生任何调试信息(编译比较快);Line Numbers Only,仅生成全局的和外部符号的调试信息到.OBJ文件或.EXE文件,减小目标文件的尺寸;C 7.0- Compatible,记录调试器用到的所有符号信息到.OBJ文件和.EXE文件;Program Database,创建.PDB文件记录所有调试信息;Program Database for "Edit & Continue",创建.PDB文件记录所有调试信息,并且支持调试时编辑。

  2) C++ Language:pointer_to_member representation用来设置类定义/引用的先后关系,一般为Best-Case Always表示在引用类之前该类肯定已经定义了;Enable Exception Handling,进行同步的异常处理;Enable Run-Time Type Information迫使编译器增加代码在运行时进行对象类型检查;Disable Construction Displacements,设置类构造/析构函数调用虚函数问题。

  3) Code Generation:Processor表示代码指令优化,可以为80386、80486、Pentium、Pentium Pro,或者Blend表示混合以上各种优化。Use run-time library用以指定程序运行时使用的运行时库(单线程或多线程,Debug版本或Release版本),有一个原则就是,一个进程不要同时使用几个版本的运行时库。Single-Threaded,静态连接LIBC.LIB库;Debug Single-Threaded,静态连接LIBCD.LIB库;Multithreaded,静态连接LIBCMT.LIB库;Debug Multithreaded,静态连接LIBCMTD.LIB库;Multithreaded DLL,动态连接MSVCRT.DLL库;Debug Multithreaded DLL,动态连接MSVCRTD.DLL库。连接了单线程库就不支持多线程调用,连接了多线程库就要求创建多线程的应用程序。

  Calling convention可以用来设定调用约定,有三种:__cdecl、__fastcall和__stdcall。各种调用约定的主要区别在于,函数调用时,函数的参数是从左到右压入堆栈还是从右到左压入堆栈;在函数返回时,由函数的调用者来清理压入堆栈的参数还是由函数本身来清理;以及在编译时对函数名进行的命名修饰(可以通过Listing Files看到各种命名修饰方式)。Struct member alignment用以指定数据结构中的成员变量在内存中是按几字节对齐的,根据计算机数据总线的位数,不同的对齐方式存取数据的速度不一样。这个参数对数据包网络传输等应用尤为重要,不是存取速度问题,而是数据位的精确定义问题,一般在程序中使用#pragma pack来指定。

  4) Customize:Disable Language Extensions,表示不使用微软为标准C做的语言扩展;Eliminate Duplicate Strings,主要用于字符串优化(将字符串放到缓充池里以节省空间),使用这个参数,使得

char *sBuffer = "This is a character buffer";

char *tBuffer = "This is a character buffer";


  sBuffer和tBuffer指向的是同一块内存空间;Enable Function-Level Linking ,告诉编译器将各个函数按打包格式编译;Enables minimal rebuild,通过保存关联信息到.IDB文件,使编译器只对最新类定义改动过的源文件进行重编译,提高编译速度;Enable Incremental Compilation,同样通过.IDB文件保存的信息,只重编译最新改动过的函数;Suppress Startup Banner and Information Messages,用以控制参数是否在output窗口输出。

  5) Listing Files:Generate browse info的功能上面已经提到过。这里可以进行更多的设置。Exclude Local Variables from Browse Info表示是否将局部变量的信息放到.SBR文件中。Listing file type可以设置生成的列表信息文件的内容:Assembly-Only Listing仅生成汇编代码文件(.ASM扩展名);Assembly With Machine Code生成机器代码和汇编代码文件(.COD扩展名);Assembly With Source Code生成源代码和汇编代码文件(.ASM扩展名);Assembly, Machine Code,and Source生成机器码、源代码和汇编代码文件(.COD扩展名)。Listing file name为生成的信息文件的路径,一般为Debug或Release目录下,生成的文件名自动取源文件的文件名。

  6) Optimizations:代码优化设置。可以选择Maximize Speed生成最快速的代码,或Minimize Size生成最小尺寸的程序,或者Customize定制优化。定制的内容包括:

  Assume No Aliasing,不使用别名(提高速度);

  Assume Aliasing Across Function Calls,仅函数内部不使用别名;

  Global Optimizations,全局优化,比如经常用到的变量使用寄存器保存,或者循环内的计算优化,如

i = -100;

while( i < 0 ){ i += x + y;}


  会被优化为


i = -100;
t = x + y;
while( i < 0 ){i += t;}
Generate Intrinsic Functions,使用内部函数替换一些函数调用(提高速度);
Improve Float Consistency,浮点运算方面的优化;
Favor Small Code,程序(exe或dll)尺寸优化优先于代码速度优化;
Favor Fast Code,程序(exe或dll)代码速度优化优先于尺寸优化;
Frame-Pointer Omission,不使用帧指针,以提高函数调用速度;
Full Optimization,组合了几种参数,以生成最快的程序代码。


  Inline function expansion,内联函数扩展的三种优化(使用内联可以节省函数调用的开销,加快程序速度):Disable不使用内联;Only __inline,仅函数定义前有inline或__inline标记使用内联;Any Suitable,除了inline或__inline标记的函数外,编译器“觉得”应该使用内联的函数,都使用内联。

  7) Precompiled Headers:预编译头文件的设置。使用预编译可以提高重复编译的速度。VC一般将一些公共的、不大变动的头文件(比如afxwin.h等)集中放到stdafx.h中,这一部分代码就不必每次都重新编译(除非是Rebuild All)。

  8) Preprocessor:预编译处理。可以定义/解除定义一些常量。Additional include directories,可以指定额外的包含目录,一般是相对于本项目的目录,如..Include。


  连接参数的设置。主要通过VC的菜单项Project->Settings->Link页来完成。我们可以看到这一页的最下面Project Options中的内容,一般如下:

/nologo /subsystem:windows /incremental:yes /pdb:"Debug/WritingDlgTest.pdb" /debug /machi
ne:I386 /out:"Debug/WritingDlgTest.exe" /pdbtype:sept

  下面我们分别来看一下Category中的各项设置。

  1) General:一些总体设置。可以设置生成的文件路径、文件名;连接的库文件;Generate debug info,生成Debug信息到.PDB文件(具体格式可以在Category->Debug中设置);Ignore All Default Libraries,放弃所有默认的库连接;Link Incrementally,通过生成. ILK文件实现递增式连接以提高后续连接速度,但一般这种方式下生成的文件(EXE或DLL)较大;Generate Mapfile,生成.MAP文件记录模块相关信息;Enable Profiling,这个参数通常与Generate Mapfile参数同时使用,而且如果产生Debug信息的话,不能用.PDB文件,而且必须用Microsoft Format。

  2) Customize:这里可以进行使用程序数据库文件的设置。Force File Output ,强制产生输出文件(EXE或DLL);Print Progress Messages,可以将连接过程中的进度信息输出到Output窗口。

  3) Debug:设置是否生成调试信息,以及调试信息的格式。格式可以有Microsoft Format、COFF Format(Common Object File Format)和Both Formats三种选择;Separate Types,表示将Debug格式信息以独立的.PDB文件存放,还是直接放在各个源文件的.PDB文件中。选中的话,表示采用后者的方式,这种方式调试启动比较快。

  4) Input:这里可以指定要连接的库文件,放弃连接的库文件。还可以增加额外的库文件目录,一般是相对于本项目的目录,如..Lib。Force Symbol References,可以指定连接特定符号定义的库。

  5) Output:Base Address可以改变程序默认的基地址(EXE文件默认为0x400000,DLL默认为x10000000),操作系统装载一个程序时总是试着先从这个基地址开始。Entry-Point Symbol可以指定程序的入口地址,一般为一个函数名(且必须采用__stdcall调用约定)。一般Win32的程序,EXE的入口为WinMain,DLL的入口为DllEntryPoint;最好让连接器自动设置程序的入口点。默认情况下,通过一个C的运行时库函数来实现:控制台程序采用mainCRTStartup (或wmainCRTStartup)去调用程序的main (或wmain)函数;Windows程序采用WinMainCRTStartup (或 wWinMainCRTStartup)调用程序的WinMain (或 wWinMain,必须采用__stdcall调用约定);DLL采用_DllMainCRTStartup调用DllMain函数(必须采用__stdcall调用约定)。Stack allocations,用以设置程序使用的堆栈大小(请使用十进制),默认为1兆字节。Version Information告诉连接器在EXE或DLL文件的开始部分放上版本号。


  值得注意的是,上面各个参数是大小写敏感的;在参数后加上“-”表示该参数无效;各个参数值选项有“*”的表示为该参数的默认值;可以使用页右上角的“Reset”按钮来恢复该页的所有默认设置。


  其它一些参数设置

  1) Project->Settings->General,可以设置连接MFC库的方式(静态或动态)。如果是动态连接,在你的软件发布时不要忘了带上MFC的DLL。

  2) Project->Settings->Debug,可以设置调试时运行的可执行文件,以及命令行参数等。

  3) Project->Settings->Custom Build,可以设置编译/连接成功后自动执行一些操作。比较有用的是,写COM时希望VC对编译通过的COM文件自动注册,可以如下设置:

   Description: Register COM

   Commands: regsvr32 /s /c $(TargetPath)

   echo regsvr32 exe.time > $(TargetDir)$(TargetName).trg

   Outputs: $(TargetDir)$(TargetName).trg

  4) Tools->Options->Directories,设置系统的Include、Library路径。


  一些小窍门

  1) 有时候,你可能在编译的时候,计算机突然非法关机了(可能某人不小心碰了电源或你的内存不稳定等原因)。当你重启机器后打开刚才的项目,重新进行编译,发现VC会崩掉。你或许以为你的VC编译器坏了,其实不然(你试试编译其它项目,还是好的!),你只要将项目的.ncb、.opt、.aps、.clw文件以及Debug、Release目录下的所有文件都删掉,然后重新编译就行了。
  2) 如果你想与别人共享你的源代码项目,但是把整个项目做拷贝又太大。你完全可以删掉以下文件:.dsw、.ncb、.opt、.aps、.clw、. plg文件以及Debug、Release目录下的所有文件。
  3) 当你的Workspace中包含多个Project的时候,你可能不能直观地、一眼看出来哪个是当前项目。可以如下设置:Tools->Options->Format,然后在Category中选择Workspace window,改变其默认的字体(比如设成Fixedsys)就行了。
  4) 如何给已有的Project改名字?将该Project关掉。然后以文本格式打开.dsp文件,替换原来的Project名字即可。
  5) VC6对类成员的智能提示功能很有用,但有时候会失灵。你可以先关掉项目,将.clw和.ncb删掉,然后重新打开项目,点击菜单项View->ClassWizard,在弹出的对话框中按一下“Add All”按钮;重新Rebuild All。应该可以解决问题。



23 09, 2006

VC编译语法解释

作者 fevair 18:05 | 静态链接网址 | 最新回复 (0) | 引用 (0) | C++/VC

VC- Project Setting-Debug-Project Option语法解释
-优化-
/O1 最小化空间 minimize space
/Op[-] 改善浮点数一致性 improve floating-pt consistency
/O2 最大化速度 maximize speed
/Os 优选代码空间 favor code space
/Oa 假设没有别名 assume no aliasing
/Ot 优选代码速度 favor code speed
/Ob 内联展开(默认 n=0) inline expansion (default n=0)
/Ow 假设交叉函数别名 assume cross-function aliasing
/Od 禁用优化(默认值) disable optimizations (default)
/Ox 最大化选项。(/Ogityb2 /Gs) maximum opts. (/Ogityb1 /Gs)
/Og 启用全局优化 enable global optimization
/Oy[-] 启用框架指针省略 enable frame pointer omission
/Oi 启用内建函数 enable intrinsic functions
-代码生成-
/G3 为 80386 进行优化 optimize for 80386
/G4 为 80486 进行优化 optimize for 80486
/GR[-] 启用 C++ RTTI enable C++ RTTI
/G5 为 Pentium 进行优化 optimize for Pentium
/G6 为 Pentium Pro 进行优化 optimize for Pentium Pro
/GX[-] 启用 C++ 异常处理(与 /EHsc 相同) enable C++ EH (same as /EHsc)
/EHs 启用同步 C++ 异常处理 enable synchronous C++ EH
/GD 为 Windows DLL 进行优化 optimize for Windows DLL
/GB 为混合模型进行优化(默认) optimize for blended model (default)
/EHa 启用异步 C++ 异常处理 enable asynchronous C++ EH
/Gd __cdecl 调用约定 __cdecl calling convention
/EHc extern“C”默认为 nothrow extern "C" defaults to nothrow
/Gr __fastcall 调用约定 __fastcall calling convention
/Gi[-] 启用增量编译 enable incremental compilation
/Gz __stdcall 调用约定 __stdcall calling convention
/Gm[-] 启用最小重新生成 enable minimal rebuild
/GA 为 Windows 应用程序进行优化 optimize for Windows Application
/Gf 启用字符串池 enable string pooling
/QIfdiv[-] 启用 Pentium FDIV 修复 enable Pentium FDIV fix
/GF 启用只读字符串池 enable read-only string pooling
/QI0f[-] 启用 Pentium 0x0f 修复 enable Pentium 0x0f fix
/Gy 分隔链接器函数 separate functions for linker
/GZ 启用运行时调试检查 enable runtime debug checks
/Gh 启用钩子函数调用 enable hook function call
/Ge 对所有函数强制堆栈检查 force stack checking for all funcs
/Gs[num] 禁用堆栈检查调用 disable stack checking calls
-输出文件-
/Fa[file] 命名程序集列表文件 name assembly listing file
/Fo 命名对象文件 name object file
/FA[sc] 配置程序集列表 configure assembly listing
/Fp 命名预编译头文件 name precompiled header file
/Fd[file] 命名 .PDB 文件 name .PDB file
/Fr[file] 命名源浏览器文件 name source browser file
/Fe 命名可执行文件 name executable file
/FR[file] 命名扩展 .SBR 文件 name extended .SBR file
/Fm[file] 命名映射文件 name map file
-预处理器-
/FI 命名强制包含文件 name forced include file
/C 不吸取注释 don't strip comments
/U 移除预定义宏 remove predefined macro
/D{=|#} 定义宏 define macro
/u 移除所有预定义宏 remove all predefined macros
/E 将预处理定向到标准输出 preprocess to stdout
/I 添加到包含文件的搜索路径 add to include search path
/EP 将预处理定向到标准输出,不要带行号 preprocess to stdout, no #line
/X 忽略“标准位置” ignore "standard places"
/P 预处理到文件 preprocess to file
-语言-
/Zi 启用调试信息 enable debugging information
/Zl 忽略 .OBJ 中的默认库名 omit default library name in .OBJ
/ZI 启用调试信息的“编辑并继续”功能 enable Edit and Continue debug info
/Zg 生成函数原型 generate function prototypes
/Z7 启用旧式调试信息 enable old-style debug info
/Zs 只进行语法检查 syntax check only
/Zd 仅要行号调试信息 line number debugging info only
/vd{0|1} 禁用/启用 vtordisp disable/enable vtordisp
/Zp[n] 在 n 字节边界上包装结构 pack structs on n-byte boundary
/vm 指向成员的指针类型 type of pointers to members
/Za 禁用扩展(暗指 /Op) disable extensions (implies /Op)
/noBool 禁用“bool”关键字 disable "bool" keyword
/Ze 启用扩展(默认) enable extensions (default)
- 杂项 -
/?, /help 打印此帮助消息 print this help message
/c 只编译,不链接 compile only, no link
/W 设置警告等级(默认 n=1) set warning level (default n=1)
/H 最大化外部名称长度 max external name length
/J 默认 char 类型是 unsigned default char type is unsigned
/nologo 取消显示版权消息 suppress copyright message
/WX 将警告视为错误 treat warnings as errors
/Tc 将文件编译为 .c compile file as .c
/Yc[file] 创建 .PCH 文件 create .PCH file
/Tp 将文件编译为 .cpp compile file as .cpp
/Yd 将调试信息放在每个 .OBJ 中 put debug info in every .OBJ
/TC 将所有文件编译为 .c compile all files as .c
/TP 将所有文件编译为 .cpp compile all files as .cpp
/Yu[file] 使用 .PCH 文件 use .PCH file
/V 设置版本字符串 set version string
/YX[file] 自动的 .PCH 文件 automatic .PCH
/w 禁用所有警告 disable all warnings
/Zm 最大内存分配(默认为 %) max memory alloc (% of default)

-链接-
/MD 与 MSVCRT.LIB 链接 link with MSVCRT.LIB
/MDd 与 MSVCRTD.LIB 调试库链接 link with MSVCRTD.LIB debug lib
/ML 与 LIBC.LIB 链接 link with LIBC.LIB
/MLd 与 LIBCD.LIB 调试库链接 link with LIBCD.LIB debug lib
/MT 与 LIBCMT.LIB 链接 link with LIBCMT.LIB
/MTd 与 LIBCMTD.LIB 调试库链接 link with LIBCMTD.LIB debug lib
/LD 创建 .DLL Create .DLL
/F 设置堆栈大小 set stack size
/LDd 创建 .DLL 调试库 Create .DLL debug libary
/link [链接器选项和库] [linker options and libraries]



23 09, 2006

C++开发常用工具

作者 fevair 18:03 | 静态链接网址 | 最新回复 (0) | 引用 (0) | C++/VC

开发环境
  ---->Turbo c

  DOS时代c语言开发的经典工具,目前适合两类人使用:c语言beginner(尤其是学生一族),具有怀旧情节的专业人士:)

  ---->Visual C++ 6.0/7.0

  稳定而强大的IDE开发环境,具有丰富的调试功能,定制宏的功能也是其一大特色。Microsoft的经典之作,功能强大自不必言说。附带的一些工具也很不错,比如:Spy++。但编译器较之同类,支持c++标准的程度不够好,尤其6.0及以前的版本。

  ---->BCB

  Borland的C++ Builder是可以与VC匹敌的另一个功能强大的IDE,速度和稳定性稍逊,但对c++标准支持的程度较好。


  ---->Cygwin

  Windows平台下的C++编译器,基于gcc,又完全兼容Window特有的东西,比如对winsock的支持。从http://www.cygwin.com可以找到有关Cygwin的详细信息。

  ---->Dev-c++

  Windows平台下,一个类似VC、BCB的c++ IDE开发环境,属于共享软件。界面亲切优雅,size也不大,其4.9.x版有中文语言支持,无需汉化。编译器基于gcc,完全支持STL。但是对于规模较大的软件项目,恐怕难以胜任。可以从:http://www.bloodshed.net/dev/devcpp.html找到有关Dev-c++的有关信息。

  ---->Source Insight

  有着和Dev c++一样漂亮的界面,提供代码的编辑和察看功能,具有丰富的语法加亮功能,可以像VC一样自动弹出成员函数的提示,并具有快速方便的函数跳转功能(但是跳转速度似乎有点慢)。只是默认设置不适合时,需要仔细的调整和修改。无法查找经typedef之后的名字。

  辅助工具

  ---->Visual Assist

  VC IDE环境下的辅助编程工具,能识别各种关键字、函数、成员变量,自动给出tip,并自动更正大小写错误,标示拼写错误等。是VC开发的良好伴侣。

  ---->Understand for C++

  一款c/c++IDE编程的辅助工具,支持反向工程,代码导向和一些统计功能,从http://www.scitools.com可以找到有关Understand for C++的详细信息。

  程序编辑器

  ---->EditPlus

  一款很不错的文本编辑软件,功能强大却又十分轻巧。支持不同语言的语法加亮,还有Project组织功能,具有丰富的自定义功能。通过设置User Tool,可以和其他语言编译器结合,形成一个简单的IDE。

  ---->Ultra Edit

  功能和EditPlus相当,通过脚本文件提供的配置功能可以定制编辑环境,但自6.0版以后一直没多大变化,就编程而言,自定义设置没有EditPlus方便。

  ---->EMACS

  公认的世界上功能最多,最复杂的文本编辑器,其实也可以当作程序员用的编辑器。

  ---->Visual Slick Edit

  一个功能强大的程序员用编辑器。最值得一提的是其定制功能,很好用,可以和EMACS相比。自带了一套PCODE解释器,用c的语法,还可以挂接动态库。配合mingw一起使用很方便。从http://www.slickedit.com可以找到有关SlickEdit的详细信息。

  ---->IQEdit

  全功能的程序员用编辑器,界面很漂亮,从http://pwksoftware.com可以找到有关IQEdit的详细信息。

  UML/建模

  ---->Rational Rose

  强大的建模工具,早已“家喻户晓”,功过自然不必多加评说了。从http://www.rationalsoftware.com.cn可以找到有关Rational Rose的详细信息。

  ---->Visual Modeler

MS Visual Studio 6.0所附的小工具。属于Rational和MicroSoft合作的战略产品,是Rose的简化版。
---->Visio

  Microsoft的建模工具,感觉更人性化一些,但功能没有Rose多、强、专,支持正向的代码生成,以及对代码的反向工程。

  ---->Together

  另一款功能强大的建模工具,用java编写而成,口碑不错,不过速度稍稍慢了一些。从http://www.togethersoft.com可以找到有关Togather的详细信息,另外,以下网址提供了一个有关Together的教程:   http://www.cc.puv.fi/~tka/kurssit/Tietojarjestelmien_suunnittelu/together/TCCGuide6

  ---->Visual UML

  支持多种语言类型,比如:VC、VB、DELPHI、CORBA IDL等,可以直接从UML设计图生成代码,简单易用,完全适合Personal use,界面也很清爽。从http://www.visualObject.com可以找到有关Visual UML的详细信息。

  ---->SmartDraw

  通用图表制作软件,可以用来制作组织机构图、流程图、统计图表等。随带有图库,基本满足制作各类图表的需要。从http://www.smartdraw.com可以找到有关SmartDraw的详细信息。

  ---->PlayCase

  国产面向对象的建模软件,兼容UML和IDEF,轻量级软件,只是界面看起来有点简朴,乃是高展先生用Delphi完成的。

  版本控制

  ---->ClearCase

  Rational的版本控制管理软件,功能强大,可以控制多种类型的文档,甚至包括Word、Excel、PowerPoint文档。但使用复杂,不易上手,且不是免费软件。

  ---->CVS

  为基于Web的分布式协同开发提供了版本控制管理手段,且是免费软件,可以通过脚本定制功能。但在权限控制方面功能相对较弱。

  ---->VSS

  微软的版本控制管理工具,功能相对简单,适合于小型团队开发,将其整合到微软的其他开发工具中,使用起来十分方便。

  ---->SourceOffSite

  微软为开发人员提供的远程访问VSS数据库的工具,使数据库得以远程更新,以支持远程办公。其他的版本管理工具还包括:PVCS、VCS、RCS等。

  XML

  ---->expat

  用于读取和处理XML文档的c函数库,最初是James Clark的个人作品,简单轻巧,且速度快。但支持的编码方式有限,最遗憾的是不支持中文。从http://expat.sourceforge.net可以找到有关expat的详细信息。

  ---->xml4c

  IBM的XML Parser,用c++语言写就,功能超级强大。号称支持多达100种字符编码,能够支持中文,适合于大规模的xml应用。若只是很小范围的应用,则非最佳选择,毕竟,你需要“背负”约12M左右的dll的沉重负担。从http://www.alphaworks.ibm.com/tech/xml4c可以找到有关xml4c的详细信息。

  ---->Xerces c++

  Apache的XML项目,同样是c++实现,来源于IBM的xml4c,因此编程接口也是和xml4c一致的。但是目前只支持少数的字符编码,如ASCII,UTF-8,UTF-16等,不能处理包含中文字符的XML文档。从 http://xml.apache.org/xerces-c可以找到有关Xerces c++的详细信息。

  测试

  ---->CppUnit

  一个c++的单元测试框架,可以通过派生测试类的方式,定制具体的测试方案。xUnit家族的一员,从JUnit移植而来,JUnit是Java语言的单元测试框架。从http://cppuint.sourceforge.net可以找到有关CppUint的详细信息。

  ---->Rational ROBOT

  Rational的自动化测试工具,通过编写脚本的方式提供自动化测试特性。其GUI方式的脚本录制功能,有助于对GUI软件进行功能测试;其VU方式的脚本录制功能,有助于测试某些软件的数据通讯功能。

  ---->Rational Purify

  同样是Rational的自动化测试工具,不需要被测程序的源代码,可以用来检查内存访问错误、Windows API调用错误等,以完成软件的可靠性测试,属于白盒测试。

  其他的Rational测试工具还包括:TestFactory、PureCoverage、TestManager等。

  日志

  ---->log4cpp

  一个用于日志记录的c++函数库,可以将内容以定制的方式记录到不同的目的地,比如:文件、控制台syslog等,同时还可以通过控制记录级别来屏蔽掉某些无关记录。从http://log4cpp.sourceforge.net可以找到有关log4cpp的详细信息。

  注释

  ---->Doc++

  注释文档生成工具,根据源程序中的文档注释,可以输出TeX和HTML格式的文档。除了支持c/c++语言外,还支持IDL和java。仅提供命令行使用方式。从http://docpp.sourceforge.net可以找到有关Doc++的详细信息。

  ---->Doxygen

  注释文档生成工具,较之Doc++功能更为齐全,可以生成包括HTML、PDF、RTF在内的多种格式的文档,并有GUI界面,除了支持c/c++语言外,还支持IDL、java、PHP、c#等。从http://www.stack.nl/~dimitri/doxygen可以找到有关Doxygen的详细信息。



23 09, 2006

_beginthread还是CreateThread[]

作者 fevair 17:58 | 静态链接网址 | 最新回复 (0) | 引用 (0) | C++/VC

程序员对于Windows程序中应该用_beginthread还是CreateThread来创建线程,一直有所争论。本文将从对CRT源代码出发探讨这个问题。

I. 起因

今天一个朋友问我程序中究竟应该使用_beginthread还是CreateThread,并且告诉我如果使用不当可能会有内存泄漏。其实我过去对这个问题也是一知半解,为了对朋友负责,专门翻阅了一下VC的运行库(CRT)源代码,终于找到了答案。

II. CRT

CRT(C/C++ Runtime Library)是支持C/C++运行的一系列函数和代码的总称。虽然没有一个很精确的定义,但是可以知道,你的main就是它负责调用的,你平时调用的诸如strlen、strtok、time、atoi之类的函数也是它提供的。我们以Microsoft Visual.NET 2003中所附带的CRT为例。假设你的.NET 2003安装在C:Program FilesMicrosoft Visual Studio .NET 2003中,那么CRT的源代码就在C:Program FilesMicrosoft Visual Studio .NET 2003Vc7crtsrc中。既然有了这些实现的源代码,我们就可以找到一切解释了。

III. _beginthread/_endthread

这个函数究竟做了什么呢?它的代码在thread.c中。阅读代码,可以看到它最终也是通过CreateThread来创建线程的,主要区别在于,它先分配了一个_tiddata,并且调用了_initptd来初始化这个分配了的指针。而这个指针最后会被传递到CRT的线程包装函数_threadstart中,在那里会把这个指针作为一个TLS(Thread Local Storage)保存起来。然后_threadstart会调用我们传入的线程函数,并且在那个函数退出后调用_endthread。这里也可以看到,_threadstart用一个__try/__except块把我们的函数包了起来,并且在发生异常的时候,调用exit退出。(_threadstart和endthread的代码都在thread.c中)
这个_tiddata是一个什么样的结构呢?它在mtdll.h中定义,它的成员被很多CRT函数所用到,譬如int _terrno,这是这个线程中的错误标志;char* _token,strtok以来这个变量记录跨函数调用的信息,...。
那么_endthread又做了些什么呢?除了调用浮点的清除代码以外,它还调用了_freeptd来释放和这个线程相关的tiddata。也就是说,在_beginthread里面分配的这块内存,以及在线程运行过程中其它CRT函数中分配并且记录在这个内存结构中的内存,在这里被释放了。
通过上面的代码,我们可以看到,如果我使用_beginthread函数创建了线程,它会为我创建好CRT函数需要的一切,并且最后无需我操心,就可以把清除工作做得很好,可能唯一需要注意的就是,如果需要提前终止线程,最好是调用_endthread或者是返回,而不要调用ExitThread,因为这可能造成内存释放不完全。同时我们也可以看出,如果我们用CreateThread函数创建了线程,并且不对C运行库进行调用(包括任何间接调用),就不必担心什么问题了。

IV. CreateThread和CRT

或许有人会说,我用CreateThread创建线程以后,我也调用了C运行库函数,并且也使用ExitThread退出了,可是我的程序运行得好好的,既没有因为CRT没有初始化而崩溃,也没有因为忘记调用_endthread而发生内存泄漏,这是为什么呢,让我们继续我们的CRT之旅。
假设我用CreateThread创建了一个线程,我调用strtok函数来进行字符串处理,这个函数肯定是需要某些额外的运行时支持的。strtok的源代码在strtok.c中。从代码可见,在多线程情况下,strtok的第一句有效代码就是_ptiddata ptd = _getptd(),它通过这个来获得当前的ptd。可是我们并没有通过_beginthread来创建ptd,那么一定是_getptd捣鬼了。打开tidtable.c,可以看到_getptd的实现,果然,它先尝试获得当前的ptd,如果不能,就重新创建一个,因此,后续的CRT调用就安全了。可是这块ptd最终又是谁释放的呢?打开dllcrt0.c,可以看到一个DllMain函数。在VC中,CRT既可以作为一个动态链接库和主程序链接,也可以作为一个静态库和主程序链接,这个在Project Setting->Code Generations里面可以选。当CRT作为DLL链接到主程序时,DllMain就是CRT DLL的入口。Windows的DllMain可以由四种原因调用:Process Attach/Process Detach/Thread Attach/Thread Detach,最后一个,也就是当线程函数退出后但是线程还没有销毁前,会在这个线程的上下文中用Thread Detach调用DllMain,这里,CRT做了一个_freeptd(NULL),也就是说,如果有ptd,就free掉。所以说,恰巧没有发生内存泄漏是因为你用的是动态链接的CRT。
于是我们得出了一个更精确的结论,如果我没有使用那些会使用_getptd的CRT函数,使用CreateThread就是安全的。

V. 使用ptd的函数

那么,究竟那些函数使用了_getptd呢?很多!在CRT目录下搜索_getptd,你会发觉很多意想不到的函数都用到了它,除了strtok、rand这类需要保持状态的,还有所有的字符串相关函数,因为它们要用到ptd中的locale信息;所有的mbcs函数,因为它们要用到ptd中的mbcs信息,...。

VI. 测试代码

下面是一段测试代码(leaker中用到了atoi,它需要ptd):

#include
#include
#include
#include

volatile bool threadStarted = false;

void leaker()
{
std::cout << atoi( "0" ) << std::endl;
}

DWORD __stdcall CreateThreadFunc( LPVOID )
{
leaker();
threadStarted = false;
return 0;
}

DWORD __stdcall CreateThreadFuncWithEndThread( LPVOID )
{
leaker();
threadStarted = false;
_endthread();
return 0;
}

void __cdecl beginThreadFunc( LPVOID )
{
leaker();
threadStarted = false;
}

int main()
{
for(;;)
{
while( threadStarted )
Sleep( 5 );
threadStarted = true;
// _beginthread( beginThreadFunc, 0, 0 );//1
CreateThread( NULL, 0, CreateThreadFunc, 0, 0, 0 );//2
// CreateThread( NULL, 0, CreateThreadFuncWithEndThread, 0, 0, 0 );//3
}
return 0;
}

如果你用VC的多线程+静态链接CRT选项去编译这个程序,并且尝试打开1、2、3之中的一行,你会发觉只有2打开的情况下,程序才会发生内存泄漏(可以在Task Manager里面明显的观察到)。3之所以不会出现内存泄漏是因为主动调用了_endthread。

VII. 总结

如果你使用了DLL方式链接的CRT库,或者你只是一次性创建少量的线程,那么你或许可以采取鸵鸟策略,忽视这个问题。上面一节代码中第3种方法基于对CRT库的了解,但是并不保证这是一个好的方法,因为每一个版本的VC的CRT可能都会有些改变。看来,除非你的头脑清晰到可以记住这一切,或者你可以不厌其烦的每调用一个C函数都查一下CRT代码,否则总是使用_beginthread(或者它的兄弟_beginthreadex)是一个不错的选择。

 查看全文

23 09, 2006

小技巧

作者 fevair 17:49 | 静态链接网址 | 最新回复 (0) | 引用 (0) | oracle数据库开发[收集]

全数据库的导入与导出

exp username/password full=y file=yourdata.dmp grants=y rows=y
imp username/password full=y ignore=y file=yourdata.dmp grants=y

复制空表结构
create table new_table
as select * from old_table where 1=2;
复制表(含记录)
create table new_table
as select * from old_table ;

把一个用户下的表导入到另一个用户下,但需要改名

先用exp导出所有的表;
用imp将导出的表导入到新用户;
在新用户下,执行
select 'RENAME TABLE '||tname||' TO NEW_'||tname||';'
from tab
where tabtype='TABLE';
将上面的查询结果保存到一个sql文件中,处理后执行就可以了。


BFILE的用法

(1)、create or replace directory
BFILE_TEST
as
'/oracle/oradata/bfiles';

(2)、grant read on directory BFILE_TEST to SCOTT;

(3)、host ls -l /oracle/oradata/bfiles/1.TXT

(4)、connect SCOTT/TIGER
create table BFILES (ID number, TEXT bfile );

(5)、insert into BFILES values ( 1,
bfilename ( 'BFILE_TEST', '1.TXT' ) );

如何使用SQLPLUS和SVRMGRL运行脚本

(1)、用sqlplus调用:

c:script.txt的内容
startup;

命令行:sqlplus internal/oracle @c:script.txt

(2)、用svrmgrl调用:
c:script.txt的内容

connect internal/oracle;
startup;

命令行:svrmgrl @c:script.txt

DROP掉名字是小写的表(用双引号括起来)

drop table "tablename"
select * from "tablename"

日期的显示格式
注意:SIMPLIFIED CHINESE(简体中文需要" "括起来)
别的国家不用" " 例如:ENGLISH
select to_char(sysdate,'DAY','NLS_DATE_LANGUAGE=''SIMPLIFIED CHINESE''') from dual;
------------
星期四
------------

使触发器无效(login_on)

svrmgrl
connect internal/oracle
alter trigger login_on disable;

使触发器为无效alter trigger yourtriggername disable

如果是对于某一个表的所有的触发器:
alter table yourtablename disable all triggers

关于创建重建查看索引
创建索引:
CREATE INDEX IND_NAME ON TABLE_NAME(COL1,COL2,...);

重建索引:
ALTER INDEX IND_NAME REBUILD;

查看索引:

SELECT * FROM USER_INDEXES WHERE INDEX_NAME='IND_NAME';

ORACLE如何查杀用户的进程

一、

根据用户的应用程序和SQL语句,在DBA STUDIO找到用户的SESSION并断开其连接

二、

(1)、要杀掉一个session应先应知道其sid和serial#,假设你已经知道。
(2)、select paddr from v$session where sid=v_sid and serial#=v_serial#
select spid from v$process where addr=paddr(以上语句所查出的);

(3)、使用ALTER SYSTEM KILL SESSION 'v_sid,v_serial#' immediate; 试一试如不行转

三、LINUX和UNIX下
转到操作系统下执行:kill -9 spid (以上语句所查出的)

关于如何建立数据库链接(DBlink)

可以通过建立客户机数据库网络服务名的办法,将服务器的名字或是IP地址设置为你需要连接的那个机器就行

如果你要在一个应用中连接它,现在做好上步工作,然后按如下处理

建立数据库连接
CREATE DATABASE LINK DBaseLinkName CONNECT TO UserName IDENTIFIED BY Password USING 'NetServiceName';
DBaseLinkName 是建立的数据连接名称
UserName 是可以连接到的用户名
Password 是可以连接到的用户的密码
NetServiceName 是可以连接的数据库网络服务名或是数据库名

查询建立数据连接的表实例
Select * From TableName@ DBaseLinkName;

注意:如果在CREATE DATABASE LINK DBaseLinkName CONNECT TO UserName IDENTIFIED BY Password USING 'NetServiceName';中NetServiceName 是数据库名修改init.ora中:global_names = true
否则global_names = false
init.ora中:global_names = false
ORACLE中如何实现自增字段:

(1)第一种方法
ORACLE一般的做法是同时使用序列和触发器来生成一个自增字段.
CREATE SEQUENCE SEQname
INCREMENT BY 1
START WITH 1
MAXVALUE 99999999
/
CREATE TRIGGER TRGname
BEFORE INSERT ON table_name
REFERENCING
NEW AS :NEW
FOR EACH ROW
Begin
SELECT SEQname.NEXTVAL
INTO :NEW.FIELDname
FROM DUAL;
End;

(2)第二种方法:
CREATE OR REPLACE TRIGGER TR1
BEFORE INSERT ON temp_table
FOR EACH ROW
declare
com_num NUMBER;
BEGIN
SELECT MAX(ID) INTO COM_NUM FROM TEMP_TABLE;
:NEW.ID:=COM_NUM+1;
END TR1;

job的使用:

修改initsid.ora参数
job_queue_processes = 4 8i,9i (允许同时执行的JOB数)
job_queue_interval = 10 8i
job_queue_keep_connections=true 8i

DBMS_JOB.SUBMIT(:jobno,//job号
'your_procedure;',//要执行的过程
trunc(sysdate)+1/24,//下次执行时间
'trunc(sysdate)+1/24+1'//每次间隔时间
);
删除job:dbms_job.remove(jobno);
修改要执行的操作:dbms_job.what(jobno,what);
修改下次执行时间:dbms_job.next_date(job,next_date);
修改间隔时间:dbms_job.interval(job,interval);
停止job:dbms.broken(job,broken,nextdate);
启动job:dbms_job.run(jobno);

注意:修改后一定要COMMIT;

例子:
VARIABLE jobno number;
begin
DBMS_JOB.SUBMIT(:jobno,
'Procdemo;',//Procdemo为过程名称
SYSDATE, 'SYSDATE + 1/720');
commit;
end;

Oracle常见服务

几个主要的:

OracleOraHome81TNSListener 监听服务
OracleServiceSID ORACLE服务
OracleOraHome81Agent 智能代理服务
OracleOraHome81CMan 连接管理服务
OracleOraHome81HTTPServer APACHE WEB 服务
OracleOraHome81ManagementServer ORACLE 企业管理器服务
OracleOraHome81Names ORACLE命名服务

剩下的也不常用。

ORACLE的热备份

在不关闭数据库的时候进行ORACLE的备份。

原理停复杂的,你去找本书看看吧。

举个简单的例子:备份表空间USERS

ALTER TABLESPACE USERS BEGIN BACKUP
COPY USERS TABLESPACE 的数据文件到备份目录
ALTER TABLESPACE USERS END BACKUP

导致索引不起作用的解决办法

是由optimizer_mode参数引起的,该参数的默认值为choose,即为如表有statis则查询走基于cost的方式,否则走基于rule的方式,因些你可以有以下几个解决方法。
(1)、简单的在init.ora中设optimizer_mode=rule,重起数据库。
(2)、使用analyze table table_name(索引基表) delete statistics;
(3)、最后一个万能办法,将表和索引drop掉,重建。

删除重复列的方法

(1) DELETE FROM table_name A WHERE ROWID > (
SELECT min(rowid) FROM table_name B
WHERE A.key_values = B.key_values);
(2) create table table2 as select distinct * from table1;
drop table1;
rename table2 to table1;
(3) Delete from mytable where rowid not in(
select max(rowid) from mytable
group by column_name );
(4) delete from mytable t1
where exists (select 'x' from my_table t2
where t2.key_value1 = t1.key_value1
and t2.key_value2 = t1.key_value2
...
and t2.rowid > t1.rowid);

oracle如何设置查询超时

select /*+ timeout 30*/ * from veryLargeTable

修改字符集

(1)、ALTER DATABAE CHARACTER SET SIMPLIFIED CHINESE_CHINA.ZHS16GBK ;

(2)、update props$ set value$='ZHS16CGB231280'
where name='NLS_CHARACTERSET';
update props$ set value$='ZHS16CGB231280'
where name='NLS_NCHAR_CHARACTERSET';

建议不使用(2)

注意:
(1)、执行ALTER DATABASE CHARACTER SET必须有SYSDBA权限,并且在STARTUP RESTRICT模式下执行
(2)、原字符集必须是目标字符集的一个真子集(就是浪子所说的只能从WE8ISO8859P1转到ZHS16GBK的原因)
(3)、CLOB字段装换可能有问题,建议在转换以前把有CLOB字段的表导出后DROP,转换以后再导回
(4)、该转换不可逆,所以在做这个操作以前建议做数据库全备份

修改数据库名字

(1)、启动svrmgrl,以文本方式备份控制文件
oracle>svrmgrl
svrmgrl>connect internal
svrmgrl>alter system backup controlfile to trace
(2)、编辑产生的跟踪文件,在udump目录下
改CREATE CONTROLFILE REUSE DATABASE "CTC" NORESETLOGS ARCHIVELOG
中的REUSE为SET
然后把create controlfile这段语句拷出
(3)、正常宕库,后启动到nomount下
svrmgrl>shutdown immediate
svrmgrl>startup nomount
(4)、执行create controlfile那段语句
(5)、打开数据库
 svrmgrl>alter database open
 如提示用resetlogs选项则使用
svrmgrl>alter database open resetlogs
(8)、相应修改初始化参数

如何知道一个表空间还有多少可以用

(1)、
SELECT upper(f.tablespace_name) 表空间名,
d.Tot_grootte_Mb "表空间大小(M)",
d.Tot_grootte_Mb - f.total_bytes "已使用空间(M)",
round((d.Tot_grootte_Mb - f.total_bytes) / d.Tot_grootte_Mb * 100,2) "使用比",
f.total_bytes "空闲空间(M)",
f.max_bytes "最大块(M)"
FROM
(SELECT tablespace_name,
round(SUM(bytes)/(1024*1024),2) total_bytes,
round(MAX(bytes)/(1024*1024),2) max_bytes
FROM sys.dba_free_space
GROUP BY tablespace_name) f,
(SELECT dd.tablespace_name, round(SUM(dd.bytes)/(1024*1024),2) Tot_grootte_Mb
FROM sys.dba_data_files dd
GROUP BY dd.tablespace_name) d
WHERE d.tablespace_name = f.tablespace_name
ORDER BY 4 DESC
(2)、select tablespace_name,round(sum(bytes)/1024/1024,2) "M" from dba_free_space
group by tablespace_name

使索引无效

ALTER INDEX idx UNUSABLE;
ALTER INDEX idx_acctno DISABLE;(only to a function based index)
--------------------------------------------------------------------------------------------

在SQLPLUS中调用存储过程

SET SERVEROUTPUT ON
declare
out_param varchar2(100);
begin
your_proc(1,out_param);
dbms_output.put_line(out_param);
end;
/
SET SERVEROUTPUT OFF

ORACLE9i中删除表空间中数据文件的方法

drop tablespace tbsname including contents

分析表
analyze table mzbs.db_code ESTIMATE STATISTICS SAMPLE 20 PERCENT;



23 09, 2006

LINUXUNIX下自动启动ORACLE服务

作者 fevair 17:40 | 静态链接网址 | 最新回复 (0) | 引用 (0) | oracle数据库开发[收集]

(1)

!/bin/sh

# chkconfig: 345 51 49
# description: starts the oracle dabase deamons
#

ORA_HOME=/u01/app/oracle/product/8.1.7
ORA_OWNER=oracle
case "$1" in
'start')
echo -n "Starting Oracle8i: "
su - $ORA_OWNER -c $ORA_HOME/bin/dbstart
touch /var/lock/subsys/oracle8i
echo
;;

'stop')

echo -n "Shutting down Oracle8i: "
su - $ORA_OWNER -c $ORA_HOME/bin/dbshut
rm -f /var/lock/subsys/oracle8i
echo
;;

'restart')

echo -n "Restarting Oracle8i: "
$0 stop
$0 start
echo
;;

*)
echo "Usage: oracle8i { start | stop | restart }"
exit 1

esac
exit 0

我仿照su - $ORA_OWNER -c $ORA_HOME/bin/dbshut 的形式
添加su - $ORA_OWNER -c $ORA_HOME/bin/lsnrctl start
但是在系统启动的时候listener启动不了

(2)

/etc/rc.local
改成如下就可以了
touch /var/lock/subsys/local
#echo 2147483648 > /proc/sys/kernel/shmmax
echo -n "Starting Oracle Database:"
date +"%D %T %a"
su - oracle -c "lsnrctl start"
#su - oracle -c "sqlplus /nolog @startmaster.sql"
echo -n "Oracle Database Started:"
date +"%D %T %a"
-------------
第一个#是改共享内存大小的
第二个#是启动数据库的。

(3)
ftp://ftp.rpmfind.net/linux/rhcontri ... lerun9i-1.0-1.i386.rpm

下载这个软件包并安装。

里面每个文件都有一些要修改的地方。配置完成之后,就可以在系统服务配置中找到它,选中它就可能以自启动了。



23 09, 2006

ORACLE的临时表

作者 fevair 17:39 | 静态链接网址 | 最新回复 (0) | 引用 (0) | oracle数据库开发[收集]

CREATE GLOBAL TEMPORARY TABLE TABLENAME (
COL1 VARCHAR2(10),
COL2 NUMBER
) ON COMMIT PRESERVE(DELETE) ROWS ;
这种临时表不占用表空间,而且不同的SESSION之间互相看不到对方的数据
在会话结束后表中的数据自动清空,如果选了DELETE ROWS,则在提交的时候即清空数据,PRESERVE则一直到会话结束

Oracle8i中,可以创建以下两种临时表:
(1)会话特有的临时表
CREATE GLOBAL TEMPORARY ()
ON COMMIT PRESERVE ROWS;

(2)事务特有的临时表
CREATE GLOBAL TEMPORARY ()
ON COMMIT DELETE ROWS;
CREATE GLOBAL TEMPORARY TABLE MyTempTable
所建的临时表虽然是存在的,但是你试一下insert 一条记录然后用别的连接登上去select,记录是空的,明白了吧,我把下面两句话再贴一下:
--ON COMMIT DELETE ROWS 说明临时表是事务指定,每次提交后ORACLE将截断表(删除全部行)
--ON COMMIT PRESERVE ROWS 说明临时表是会话指定,当中断会话时ORACLE将截断表。
冲突的问题更本不用考虑.

临时表只是保存当前会话(session)用到的数据,数据只在事务或会话期间存在。

通过CREATE GLOBAL TEMPORARY TABLE命令创建一个临时表,对于事务类型的临时表,
数据只是在事务期间存在,对于会话类型的临时表,数据在会话期间存在。

会话的数据对于当前会话私有。每个会话只能看到并修改自己的数据。DML锁不会加到
临时表的数据上。下面的语句控制行的存在性。

● ON COMMIT DELETE ROWS 表名行只是在事务期间可见
● ON COMMIT PRESERVE ROWS 表名行在整个会话期间可见

可以对临时表创建索引,视图,出发器,可以用export和import工具导入导出表的
定义,但是不能导出数据。表的定义对所有的会话可见。

例如:
CREATE GLOBAL TEMPORARY TABLE TEMP_TAB1(
table_name VARCHAR2(20),
primary_key VARCHAR2(100),
field VARCHAR2(1000))
ON COMMIT PRESERVE ROWS;

CREATE GLOBAL TEMPORARY TABLE TEMP_TAB2(
table_name VARCHAR2(20),
primary_key VARCHAR2(100),
field VARCHAR2(1000))
ON COMMIT DELETE ROWS;



23 09, 2006

JOB中日期的使用

作者 fevair 17:31 | 静态链接网址 | 最新回复 (0) | 引用 (0) | oracle数据库开发[收集]

每个月1号:
last_day(sysdate)+1
每个季度的第一天:
to_date(decode(to_char(sysdate,'q'),'1',to_char(sysdate,'yyyy')||'0101',
'2',to_char(sysdate,'yyyy')||'0401','3',to_char(sysdate,'yyyy')||'0701',
'4',to_char(sysdate,'yyyy')||'1001'),'yyyymmdd')
每天:
sysdate+1
每个星期几:
decode(to_char(sysdate,'w'),'1',sysdate+7,
to_char(sysdate,'w'),'2',sysdate+6,to_char(sysdate,'w'),'3',sysdate+5,
to_char(sysdate,'w'),'4',sysdate+4,to_char(sysdate,'w'),'5',sysdate+3,
to_char(sysdate,'w'),'6',sysdate+2,to_char(sysdate,'w'),'7',sysdate+1)

每个星期x下午三点:interval(21, 'next_day(trunc(sysdate),x+1)+15/24');

每个季度的第一个星期x:
interval(21, 'next_day(trunc(sysdate,''Q''),3),5)');



23 09, 2006

表空间管理和用户管理

作者 fevair 17:27 | 静态链接网址 | 最新回复 (0) | 引用 (0) | oracle数据库开发[收集]

--查看表空间和数据文件

select file_name,tablespace_name,autoextensible from dba_data_files;

--数据表空间

CREATE TABLESPACE USER_DATA
LOGGING
DATAFILE 'D:ORACLEORADATAORCLtest.DBF' SIZE 50m REUSE ,
'c:USERS01112.DBF' SIZE 50m REUSE
AUTOEXTEND
ON NEXT 1280K MAXSIZE 16383M EXTENT MANAGEMENT LOCAL

--临时表空间

CREATE TEMPORARY
TABLESPACE USER_DATA_TEMP TEMPFILE 'D:TEMP0111.DBF'
SIZE 50M REUSE AUTOEXTEND
ON NEXT 1024K MAXSIZE 16383M EXTENT MANAGEMENT LOCAL UNIFORM
SIZE 1024K


--增加数据文件

ALTER TABLESPACE USER_DATA
ADD DATAFILE 'c:USERS01113.DBF' SIZE 50M;

ALTER TABLESPACE USER_DATA
ADD DATAFILE 'c:USERS01114.DBF' SIZE 50M
AUTOEXTEND ON
;


--删除表空间

DROP TABLESPACE USER_DATA INCLUDING CONTENTS;


--修改数据文件大小
ALTER DATABASE
DATAFILE 'c:USERS01113.DBF' RESIZE 40M;

--创建用户、赋予权限

CREATE USER USER_DATA PROFILE DEFAULT IDENTIFIED BY USER_DATA
DEFAULT
TABLESPACE USER_DATA TEMPORARY
TABLESPACE USER_DATA ACCOUNT UNLOCK;

GRANT CONNECT TO USER_DATA;
GRANT RESOURCE TO USER_DATA;

--把表移到另一个表空间
ALTER TABLE TABLENAME MOVE TABLESPACE TABLESPACENAME;

--创建索引

CREATE INDEX INDEXNAME ON TABLENAME(COLUMNNAME);

CREATE INDEX INDEXNAME ON TABLENAME(COLUMNNAME) TABLESPACE TABLESPACENAME;

--重新建立索引

ALTER INDEX INDEXNAME REBUILD TABLESPACE TABLESPACE;


--创建表

CREAE TABLE TABLENAME
(COLUMN1 COLUTYPE DEFAULT(VALUE) NOT NULL)
(COLUMN2 COLUTYPE DEFAULT(VALUE) NOT NULL);


--建表的索引存储分配


CREATE TABLE summit.employee(id NUMBER(7) CONSTRAINT employee_id_pk PRIMARY KEY DEFERRABLE USING INDEX STORAGE(INITIAL 100K NEXT 100K)
TABLESPACE indx,
last_name VARCHAR2(25) CONSTRAINT employee_last_name_nn NOT NULL,
dept_id NUMBER(7))
TABLESPACE data;


--建立主键

ALTER TABLE TABLENAME
ADD CONSTRAINT CONSTRAINTNAME PRIMARY KEY(COLUMN1,COLUMN2)


--使约束无效

ALTER TABLE TABLENAME ENABLE NOVALIDATE CONSTRAINT CONSTRANAME;

ALTER TABLE TABLENAME ENABLE VALIDATE CONSTRAINT CONSTRANAME;

--删除约束

ALTER TABLE TABLENAME DROP CONSTRAINT constraintname;

DROP TABLE TABLENAEM CASCADE CONSTRAINTS;(删除表后将所用的外键删除)

--给表增加列

ALTER TABLE TABLENAME
ADD COLUMN COLUTYPE DEFAULT(VALUE) NOT NULL;

--给列增加缺省值

ALTER TABLE TABLENAME
MODIFY COLUMNNAME DEFAULT(VALUE) NOT NULL;


--给表增加外键
ALTER TABLE TABLENAME
ADD CONSTRAINT CONSTRAINTNAME
FOREIGN KEY(COLUMN) REFERENCES TABLE1NAME(COLUMN1);

1、分析表
analyze table mzbs.db_code ESTIMATE STATISTICS SAMPLE 20 PERCENT;


2、表空间管理和用户管理

--查看表空间和数据文件

select file_name,tablespace_name,autoextensible from dba_data_files;

--数据表空间

CREATE TABLESPACE USER_DATA
LOGGING
DATAFILE 'D:ORACLEORADATAORCLtest.DBF' SIZE 50m REUSE ,
'c:USERS01112.DBF' SIZE 50m REUSE
AUTOEXTEND
ON NEXT 1280K MAXSIZE 16383M EXTENT MANAGEMENT LOCAL


--修改表空间数据文件的路径

ALTER TABLESPACE app_data
RENAME
DATAFILE '/DISK4/app_data_01.dbf'
TO '/DISK5/app_data_01.dbf';


ALTER DATABASE
RENAME FILE '/DISK1/system_01.dbf'
TO '/DISK2/system_01.dbf';


--临时表空间

CREATE TEMPORARY
TABLESPACE USER_DATA_TEMP TEMPFILE 'D:TEMP0111.DBF'
SIZE 50M REUSE AUTOEXTEND
ON NEXT 1024K MAXSIZE 16383M EXTENT MANAGEMENT LOCAL UNIFORM
SIZE 1024K


--增加数据文件

ALTER TABLESPACE USER_DATA
ADD DATAFILE 'c:USERS01113.DBF' SIZE 50M;

ALTER TABLESPACE USER_DATA
ADD DATAFILE 'c:USERS01114.DBF' SIZE 50M
AUTOEXTEND ON
;


--删除表空间

DROP TABLESPACE USER_DATA INCLUDING CONTENTS;

--修改表空间的存储参数

ALTER TABLESPACE tablespacename
MINIMUM EXTENT 2M;


ALTER TABLESPACE tablespacename
DEFAULT STORAGE (
INITIAL 2M
NEXT 2M
MAXEXTENTS 999 );


--表空间联机/脱机/只读

ALTER TABLESPACE tablespacename OFFLINE/ONLINE/READ ONLY;

--修改数据文件大小
ALTER DATABASE
DATAFILE 'c:USERS01113.DBF' RESIZE 40M;

--创建用户、赋予权限

CREATE USER USER_DATA PROFILE DEFAULT IDENTIFIED BY USER_DATA
DEFAULT
TABLESPACE USER_DATA TEMPORARY
TABLESPACE USER_DATA ACCOUNT UNLOCK;

GRANT CONNECT TO USER_DATA;
GRANT RESOURCE TO USER_DATA;

3、表的管理

--创建表

CREAE TABLE TABLENAME
(COLUMN1 COLUTYPE DEFAULT(VALUE) NOT NULL)
(COLUMN2 COLUTYPE DEFAULT(VALUE) NOT NULL);


--建表的索引存储分配


CREATE TABLE summit.employee(id NUMBER(7) CONSTRAINT employee_id_pk PRIMARY KEY DEFERRABLE USING INDEX STORAGE(INITIAL 100K NEXT 100K)
TABLESPACE indx,
last_name VARCHAR2(25) CONSTRAINT employee_last_name_nn NOT NULL,
dept_id NUMBER(7))
TABLESPACE data;

--修改表的存储分配

ALTER TABLE tablename
PCTFREE 30
PCTUSED 50
STORAGE(NEXT 500K
MINEXTENTS 2
MAXEXTENTS 100);

ALTER TABLE tablename
ALLOCATE EXTENT(SIZE 500K
DATAFILE '/DISK3/DATA01.DBF');

--把表移到另一个表空间

ALTER TABLE TABLENAME MOVE TABLESPACE TABLESPACENAME;


--回收空闲的空间(回收到High-water mark)
全部回收需要TRUNCATE TABLE tablename

ALTER TABLE tablename
DEALLOCATE UNUSED;

--删除表(连同所用constraint)

DROP TABLE tablename
CASCADE CONSTRAINTS;


--给表增加列

ALTER TABLE TABLENAME
ADD COLUMN COLUTYPE DEFAULT(VALUE) NOT NULL;


--删除表中的列

ALTER TABLE tablename
DROP COLUMN columnname;


ALTER TABLE tablename
DROP COLUMN columnname
CASCADE CONSTRAINTS CHECKPOINT 1000;


--标记列不可用

ALTER TABLE tablename
SET UNUSED COLUMN columnname
CASCADE CONSTRAINTS;

--删除标记为不可用的列

ALTER TABLE tablename
DROP UNUSED COLUMNS CHECKPOINT 1000;

--继续删除列选项

ALTER TABLE tablename
DROP COLUMNS CONTINUE CHECKPOINT 1000;

--把表放到BUFFER_POOL中去

ALTER TABLE tablename
STORAGE (BUFFER_POOL RECYCLE);

--避免动态分配EXTENT

ALTER TABLE tablename ALLOCATE EXTENT;


--把表放到CACHE中去

ALTER TABLE tablename ALLOCATE CACHE/NOCACHE;


4、索引管理


--创建索引

CREATE INDEX indexname ON TABLENAME(COLUMNNAME);

CREATE INDEX indexname ON TABLENAME(COLUMNNAME) TABLESPACE TABLESPACENAME;

--重新建立索引

ALTER INDEX indexname REBUILD TABLESPACE TABLESPACE;


--索引分配参数

ALTER INDEX indexname
STORAGE(NEXT 400K
MAXEXTENTS 100);


--释放索引空间

ALTER INDEX indexname
ALLOCATE EXTENT (SIZE 200K
DATAFILE '/DISK6/indx01.dbf');

ALTER INDEX indexname
DEALLOCATE UNUSED;

--重新整理索引表空间碎片

ALTER INDEX indexname COALESCE;

--删除索引

DROP INDEX indexname


--把索引放到BUFFER_POOL中

ALTER INDEX cust_name_idx
REBUILD
STORAGE (BUFFER_POOL KEEP);


5、约束管理


--建立主键

ALTER TABLE TABLENAME
ADD CONSTRAINT CONSTRAINTNAME PRIMARY KEY(COLUMN1,COLUMN2)


--使约束无效

ALTER TABLE TABLENAME ENABLE NOVALIDATE CONSTRAINT constraintname;

ALTER TABLE TABLENAME ENABLE VALIDATE CONSTRAINT constraintname;

--删除约束

ALTER TABLE tablename DROP CONSTRAINT constraintname;

DROP TABLE tablename CASCADE CONSTRAINTS;(删除表后将所用的外键删除)


--给列增加缺省值

ALTER TABLE TABLENAME
MODIFY columnname DEFAULT(value) NOT NULL;


--给表增加外键
ALTER TABLE tablename
ADD CONSTRAINT constraintname
FOREIGN KEY(column) REFERENCES table1name(column1);


6、安全策略

--加密传输

把客户端环境变量ora_encrypt_login设为true
把服务器端参数dblink_encypt_login设为true

--数据库管理员安全策略

a、建库后立即修改SYS/SYSTEM的口令(9.2后必须修改其口令)
b、只有数据库管理员才能以SYSDBA登录系统
c、建立不同角色的管理员,分配不同的权限

比如:对象创建于维护
数据库的调整与维护
创建用户分配角色
启动关闭
恢复备份

--应用开发者的安全策略

a、开发者的特权只能在测试开发的数据库中赋予权限
b、自由开发者、受控开发者
自由开发者:create tableindexprocedurepackage
受控开发者:没有以上权限


7、日志文件管理

--切换日志文件

ALTER SYSTEM SWITCH LOGFILE;

--增加日志文件

ALTER DATABASE ADD LOGFILE
('/DISK3/log3a.rdo',
'/DISK4/log3b.rdo') size 1M;

--增加日志成员

ALTER DATABASE ADD LOGFILE MEMBER
'/DISK4/log1b.rdo' TO GROUP 1
'/DISK4/log2b.rdo' TO GROUP 2;

--删除日志文件

ALTER DATABASE DROP LOGFILE GROUP 3;

--删除日志成员

ALTER DATABASE DROP LOGFILE MEMBER '/DISK4/log2b.dbf';

--清除日志文件内容

ALTER DATABASE CLEAR LOGFILE '/DISK3/log2a.rdo';



23 09, 2006

expimp的具体用法

作者 fevair 17:24 | 静态链接网址 | 最新回复 (0) | 引用 (0) | oracle数据库开发[收集]

exp username/password@mzbs_61 full=y file=yourdata.dmp grants=y rows=y
imp username/password full=y ignore=y file=yourdata.dmp grants=y

exp mzbs/mzbs@mzbs_61 file = c:zzzzzzz.dmp grants = y rows = y
imp
mzbs/mzbs@mzbs_61 file = c:zzzzzzz.dmp grants = y ignore=y FULL=Y


(1)

exp参数:
关键字 说明(默认)
----------------------------------------------
USERID 用户名/口令
FULL 导出整个文件 (N)
BUFFER 数据缓冲区的大小
OWNER 所有者用户名列表
FILE 输出文件 (EXPDAT.DMP)
TABLES 表名列表
COMPRESS 导入一个范围 (Y)
RECORDLENGTH IO 记录的长度
GRANTS 导出权限 (Y)
INCTYPE 增量导出类型
INDEXES 导出索引 (Y)
RECORD 跟踪增量导出 (Y)
ROWS 导出数据行 (Y)
PARFILE 参数文件名
CONSTRAINTS 导出限制 (Y)
CONSISTENT 交叉表一致性
LOG 屏幕输出的日志文件
STATISTICS 分析对象 (ESTIMATE)
DIRECT 直接路径 (N)
TRIGGERS 导出触发器 (Y)
FEEDBACK 显示每 x 行 (0) 的进度
FILESIZE 各转储文件的最大尺寸
QUERY 选定导出表子集的子句

imp参数:
关键字 说明(默认)
----------------------------------------------
USERID 用户名/口令
FULL 导入整个文件 (N)
BUFFER 数据缓冲区大小
FROMUSER 所有人用户名列表
FILE 输入文件 (EXPDAT.DMP)
TOUSER 用户名列表
SHOW 只列出文件内容 (N)
TABLES 表名列表
IGNORE 忽略创建错误 (N)
RECORDLENGTH IO 记录的长度
GRANTS 导入权限 (Y)
INCTYPE 增量导入类型
INDEXES 导入索引 (Y)
COMMIT 提交数组插入 (N)
ROWS 导入数据行 (Y)
PARFILE 参数文件名
LOG 屏幕输出的日志文件
CONSTRAINTS 导入限制 (Y)
DESTROY 覆盖表空间数据文件 (N)
INDEXFILE 将表/索引信息写入指定的文件
SKIP_UNUSABLE_INDEXES 跳过不可用索引的维护 (N)
ANALYZE 执行转储文件中的 ANALYZE 语句 (Y)
FEEDBACK 显示每 x 行 (0) 的进度
TOID_NOVALIDATE 跳过指定类型 id 的校验
FILESIZE 各转储文件的最大尺寸
RECALCULATE_STATISTICS 重新计算统计值 (N)

(2)

一、建立一个expdata.sql文件

USERID=RMTAFIS/3 这里写你的用户名和密码
BUFFER=32768
OWNER=RMTAFIS 这里写导出的用户
FILE=E:ExpRMTAFIS.DMP 导出的文件,可以是相对路径
ROWs=Y
GRANTS=Y
COMPRESS=Y
CONSISTENT=Y

二、建立一个expdata.bat
exp parfile=expdata.sql
如果是805
exp80 parfile=expdata.sql
双击expdata.bat就导出数据了



23 09, 2006

ORACLE中返回游标结果集

作者 fevair 17:22 | 静态链接网址 | 最新回复 (0) | 引用 (0) | oracle数据库开发[收集]

你需要写到一个包中:
create or replace package pag_cs_power as

type c_Type is ref cursor;

FUNCTION FUN_CS_GETDICTLIST(
v_DictIndex in varchar2) return c_Type;

end pag_cs_power;

函数代码:

FUNCTION FUN_CS_GETDICTLIST(
v_DictIndex in varchar2) return c_Type
as
c_cursor c_Type;
begin
open c_cursor for
select DICTID,DICTNAME FROM SYS_DICT WHERE DICTINDEX = v_DictIndex;
return c_cursor;
end FUN_CS_GETDICTLIST;



23 09, 2006

不安装Oracle客户连接Oracle 8的方法[转载]

作者 fevair 17:18 | 静态链接网址 | 最新回复 (0) | 引用 (0) | oracle数据库开发[收集]

1、不安装Oracle客户连接Oracle 8的方法
请将以下文件拷贝到运行文件所在目录

一、ODBC动态库 :

ctl3d32.dll msvcrt40.dll odbc16gt.dll odbc32.dll odbc32gt.dll odbccp32.dll odbccr32.dll odbcint.dll

二、建立EXTRA子目录,将MSVCRT.DLL文件拷贝到该子目录下

EXTRAMSVCRT.DLL

三、ORACLE动态库及配置文件

Tnsnames.ora CORE35O.DLL NASNSNT.DLL NAUNTSNT.DLL NCRNT.DLL Nlnt.dll NLSRTL32.DLL Nnfdnt.dll NNFNNT.DLL NSNT.DLL NTNT.DLL NTTNT.DLL CIW32.DLL Ora73.dll OTRACE73.DLL Sqlnet.ora Sqltnsnt.dll CORE35.DLL

四、PB动态库

pbvm70.dll pbdwe70.dll Pbo7370.dll PBO8470.DLL pbodb70.dll libjcc.dll


Oracle的客户端不安装让pb连上,我记得以前有帖子的,你可以搜索一下。
具体步骤。
(1).先在某机器上安装好客户端(最好安装在c盘);
(2).复制此客户端oracle目录下的所有文件作为独立的oracle安装文件;
(3).搜索注册表,找到 HKey_Local_machinesoftwareoracle,把此项目及分支全部导出。
(4).打包好你的pb程序,并独立打包好oracle客户端和注册表导出文件。
(5).到干净的客户端,解开两个包,导入注册表文件,然后加入路径支持:
path=%path%;"c:Ora817bin"
这样处理,应该没有问题,因为我就是这样快速处理了几十个机器。

若不想搞注册表,你可以在程序中自己写注册表,构成Oracle客户端必要的注册表支持,至于路径,手工添加应该不难。

至于Oracle客户端那些文件不需要,这个不好说,你可以把那些bin目录下的所有exe删除,Oracle Document删除(7x兆)

至于定义Oracle服务,找到 Ora817net80adminTnsName.ora,参照格式,程序中生成一个也不麻烦。

分享到: