社区
基础和管理
帖子详情
Oracle中函数、存储过程变为无效对象
junon
2011-06-21 01:28:57
在EM中显示为无效状态
但是程序能够正常使用这些函数,这是为什么呢?
...全文
568
14
打赏
收藏
Oracle中函数、存储过程变为无效对象
在EM中显示为无效状态 但是程序能够正常使用这些函数,这是为什么呢?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
14 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
huangdh12
2011-06-22
打赏
举报
回复
无效的时候应该是不可以调用吧?。
对对象的结构修改 就有可能导致函数,存储过程失效。
需要重新编译。
junon
2011-06-22
打赏
举报
回复
[Quote=引用 7 楼 tangren 的回复:]
如果函数所依赖的某些对象变化,可能使用函数无效,
如果这些变化不影响函数通过编译,ORACLE可以自动编译,
然后正常执行。 否则,将报错!
发现函数、或者过程无效后,最好手动编译一下!
[/Quote]
恩,有可能是表结构变了。
因为之前我把一个表的字段长度变长了
Rotel-刘志东
2011-06-22
打赏
举报
回复
函数和存储过程是在程序中被调用的,具体的要看函数或存储过程是否通过编译了。
最好先调试一下函数或存储过程是否能够正确的编译。
popo666
2011-06-22
打赏
举报
回复
重新编译
tangren
2011-06-22
打赏
举报
回复
如果函数所依赖的某些对象变化,可能使用函数无效,
如果这些变化不影响函数通过编译,ORACLE可以自动编译,
然后正常执行。 否则,将报错!
发现函数、或者过程无效后,最好手动编译一下!
andhai
2011-06-22
打赏
举报
回复
有可以对应的表结构发生了变化
huangdh12
2011-06-22
打赏
举报
回复
[Quote=引用 5 楼 junon 的回复:]
阻塞会话有可能引起么?刚才发现有个会话阻塞了好几个小时
[/Quote]
阻塞会话不会引起对象失效吧。 (个人理解)
huangdh12
2011-06-22
打赏
举报
回复
显示的无效 你通过 select * from user_objects t where t.status<>'VALID' 看看是否是真的无效?
junon
2011-06-22
打赏
举报
回复
[Quote=引用 11 楼 huangdh12 的回复:]
无效的时候应该是不可以调用吧?。
对对象的结构修改 就有可能导致函数,存储过程失效。
需要重新编译。
[/Quote]
显示的无效,但是能够调用
junon
2011-06-21
打赏
举报
回复
[Quote=引用 3 楼 zhuomingwang 的回复:]
引用 2 楼 junon 的回复:
引用 1 楼 sql_xep 的回复:
重新编译一下 看看
重新编译可以解决。但是什么原因造成的呢?
可能是存储过程、函数中调用的对象发生了改变等等
[/Quote]
阻塞会话有可能引起么?刚才发现有个会话阻塞了好几个小时
sql_xeppp
2011-06-21
打赏
举报
回复
楼上说的有道理
真的不知道取什么名
2011-06-21
打赏
举报
回复
[Quote=引用 2 楼 junon 的回复:]
引用 1 楼 sql_xep 的回复:
重新编译一下 看看
重新编译可以解决。但是什么原因造成的呢?
[/Quote]
可能是存储过程、函数中调用的对象发生了改变等等
junon
2011-06-21
打赏
举报
回复
[Quote=引用 1 楼 sql_xep 的回复:]
重新编译一下 看看
[/Quote]
重新编译可以解决。但是什么原因造成的呢?
sql_xeppp
2011-06-21
打赏
举报
回复
重新编译一下 看看
VC++6.0核心编程源码.rar
第一部分 程序员必读 第一章 对程序错误的处理 在我们开始介绍Microsoft Windows应该提供的许多特性之前,我们首先必须了解Windows的各个
函数
是如何进行错误处理的。 当你调用一个Windows
函数
时,它首先要检验你传递给它的的各个参数的有效性,然后再设法执行它的任务。如果你传递了一个
无效
参数,或者由于某种原因它无法执行这项操作,那么该
函数
就会返回一个值,指明该
函数
在某种程度上运行失败了。表1-1列出了大多数Windows
函数
使用的数据类型的返回值。 表1-1 Windows
函数
常用的返回值类型 数据类型 表示失败的值 VOID 该
函数
的运行不可能失败。Windows
函数
的返回值类型很少 是VOID。 BOLL 如果
函数
运行失败,那么返回值是0,否则返回的是非0值。最 好对返回值进行测试,以确定它是0还是非0。如果它是TRUE ,则不要测试返回值。 HANDLE 如果
函数
运行失败,则返回值通常是NULL,否则返回值为 HANDLE,,用于标识你可以操作的一个
对象
。对于这个返回 值,你应该小心处理,因为有些
函数
会返回一个句柄 值INVALID_HANDLE_VALUE,它被定义为-1。该
函数
的 Platform SDK资料将会清楚地说明该
函数
是返回NULL还 是INVALID_HANDLE_VALID,以便指明
函数
运行已经失败。 PVOID 如果
函数
运行失败,则返回值是NULL,否则返回PVOID,以 标识数据块的内存地址。 LONG/DWORD 这是个难以处理的值。返回数量的
函数
通常返回LONG 或DWORD。如果由于某种原因,
函数
无法对你想要进行计数 的
对象
进行计数,那么该
函数
通常返回0或-1(根据该
函数
而定) 。如果你调用的
函数
返回了LONG/DWORD,那么请认真阅 读Platform SDK资料,以确保你能正确检查潜在的错误。 当一个Windows
函数
返回一个错误代码时,它常常可以用来了解
函数
为什么会运行失败。Microsoft公司编译了一个所有可能的错误代码的列表,并且为每个错误代码分配了一个32位的号码。 从系统内部来讲,当一个Windows
函数
检测到一个错误时,它会使用一个称为线程本地存储器的机制,将相应的错误代码号码与调用的线程关联起来。(“线程本地存储器”将在第21章
中
介绍)。这将使线程能够互相独立地运行,而不会影响各自的错误代码。当
函数
返回给你时,它的返回值就能指明一个错误已经发生。若要确定这是个什么错误,请调用GetLastError
函数
: 见原书P4的程序(1) 该
函数
只返回线程的32位错误代码。 当你拥有32位错误代码的号码时,你必须将该号码转换成更有用的某种
对象
。WinError.h头文件包含了Microsoft公司定义的错误代码的列表。下面我显示了该列表的某些内容,使你能够看到它的大概样子: 见原书P4的程序(2)和P5的程序 你可以看到,每个错误都有3种表示法:即一个消息ID(这是你可以在源代码
中
使用的一个宏,以便与GetLastError的返回值进行比较),消息文本(对错误的英文描述)和一个号码(你应该避免使用这个号码,而应该使用消息ID)。请记住,我只选择了WinError.h头文件
中
的很少一部分内容来向你进行展示,整个文件的长度超过21000行。 当Windows
函数
运行失败时,你应该立即调用GetLastError
函数
,否则,如果你调用另一个Windows
函数
,它的值很可能被改写。 说明 GetLastError能返回线程产生的最后一个错误。如果该线程调用的Windows
函数
运行成功,那么最后一个错误代码就不被改写,并且不指明运行成功。有少 数Windows
函数
并不遵循这一规则,并且它会更改最后的错误代码,但是Platform SDK资料通常指明,当
函数
运行成功时,该
函数
会更改最后的错误代码。 Windows 98 许多Windows 98的
函数
实际上是用Microsoft公司的16位Windows 3.1产 品产生的16位代码来实现的。这种比较老的代码并不通过GetLastError之类函 数来报告错误,而且Microsoft公司并没有在Windows 98
中
修改16位代码,以 支持这种错误处理方式。对于我们来说,这意味着Windows 98
中
的许多Win32
函数
在运行失败时不能设置最后的错误代码。该
函数
将返回一个值,指明运行失 败,这样你就能够发现该
函数
确实已经运行失败。但是你无法确定运行失败的原 因。 有些Windows
函数
之所以能够成功运行,那是若干个原因产生的结果。例如,创建指明的事件内核
对象
之所以能够取得成功,原因是你实际上创建了该
对象
,或者是因为已经存在带有相同名字的事件内核
对象
。你的应用程序必须知道成功的原因。为了将该信息返回给你,Microsoft公司选择使用最后错误代码机制。这样,当某些
函数
运行成功时,你就能够通过调用GetLadtError
函数
来确定其他的一些信息。对于具有这种行为特性的
函数
来说,Platform SDK资料清楚地说明了GetLastError
函数
可以这样来使用。请参见该资料,以便找出CreateEvent
函数
的例子。 当你进行调试的时候,我发现监控线程的最后错误代码是非常有用的。在Microsoft Visual studio 6.0
中
,Microsoft的调试程序支持一个非常有用的特性,即你可以配置Watch窗口,以便始终都能向你显示线程的最后错误代码的号码和该错误的英文描述。通过选定Watch窗口
中
的一行,并键入“@err,hr",你就能够做到这一点。观察图1-1,你会看到我已经调用了CreateFile
函数
。该
函数
返回INVALID_HANDLE_VALUE(-1)的HANDLE,表示它未能打开指定的文件。但是Watch窗口向我们显示最后错误代码(即如果我调用GetLastErro
函数
,该
函数
返回的错误代码)是0x00000002。该Watch窗口又进一步指明错误代码2是指“系统不能找到指定的文件。”你会发现它与WinError.h头文件
中
的错误代码2所指的字符串是相同的。 图1-1 在Visual Studio 6.0的Watch窗口
中
键入 “@err,hr",你就可以查看当前线程的最后错误代码。 Visual studio还配有一个小的实用程序,称为Error Lookup。你可以使用Error Lookup将错误代码的号码转换成它的文本描述。 见P7的Error Lookup插图 如果我在我编写的应用程序
中
发现一个错误,我可能想要向用户显示该错误的文本描述。Windows提供了一个
函数
,可以将错误代码转换成它的文本描述。该
函数
称为FormatMessage。请看下面的代码: 见原书P8的程序(1) FormatMessage
函数
的功能实际上是非常丰富的,在创建向用户显示的字符串信息时,它是人们首选的
函数
。该
函数
之所以有这样大的作用,原因之一是它很容易用多种语言来进行操作。该
函数
能够检测出用户首选的语言(在Regional Settings Control Panel小应用程序
中
设定),并返回相应的文本。当然,你首先必须自己转换字符串,然后将已转换的消息表资源嵌入你的.exe文件或DLL模块,不过,这时该
函数
会选定正确的嵌入
对象
。ErrorShow示例应用程序(本章后面将加以介绍)展示了如何调用该
函数
,以便将Microsoft公司定义的错误代码转换成它的文本描述。 有些人常常问我,Microsoft公司是否建立了一个主控列表,以显示每个Windows
函数
可能返回的所有错误代码。可惜,答案是没有这样的列表,而且Microsoft公司将永远不会建立这样的一个列表。因为在创建系统的新版本时,建立和维护该列表实在太困难了。 建立这样一个列表时存在的问题是,你可以调用一个Windows
函数
,但是该
函数
能够在内部调用另一个
函数
,而这另一个
函数
又可以调用另一个
函数
,如此类推。由于各种不同的原因,这些
函数
中
的任何一个
函数
都可能运行失败。有时,当一个
函数
运行失败时,较高级的
函数
对它进行恢复,并且仍然可以执行你想执行的操作。为了创建该主控列表,Microsoft公司必须跟踪每个
函数
的运行路径,并建立所有可能的错误代码的列表。这项工作很困难。当创建系统的新版本时,这些
函数
的运行路径就会改变。 1.1 你也能够定义自己的错误代码 好了,我已经说明Windows
函数
是如何向
函数
的调用者指明发生的错误。Microsoft公司也使你能够将该机制用于你自己的
函数
。比如说,你编写了一个你希望其他人调用的
函数
。你的
函数
可能因为这样或那样的原因而运行失败,你必须向
函数
的调用者说明它已经运行失败。 若要指明
函数
运行失败,你只需要设定线程的最后的错误代码,然后让你的
函数
返回FALSE,INVALID_HANDLE_VALUE,NULL,或者返回任何合适的信息。若要设定线程的最后错误代码,你只需要调用下面的代码: 见原书P8的程序(2) 请将你认为合适的任何32位号码传递给该
函数
。我设法使用WinError.h
中
已经存在的代码,只要该代码能够正确地指明我想要报告的错误即可。如果你认为WinError.h
中
的任何代码都不能正确地反映该错误的性质,那么你可以创建你自己的代码。错误代码是个32位的数字,它可以划分成下表所示的各个域。 位 31-30 29 28 27-16 15-0 内容 严重性 Microsoft/ 保留 设备代码 异常代码 客户 含义 0=成功 0=Microsoft 必须是0 由Microsoft 由Microsoft/ 1=供参考 公司定义的 公司定义 客户定义 2=警告 代码 3=错误 1=客户定义 的代码 这些域将在第24章
中
详细讲述。现在,你需要知道的重要域是第29位的信息。Microsoft公司规定,他们建立的所有错误代码的这个信息位均使用0。如果你创建自己的错误代码,你必须在这个信息位
中
输入1。这样,就可以确保你的错误代码与Microsoft公司目前或者将来定义的错误代码不会发生冲突, 1.2 ErrorShow示例应用程序 ErrorShow应用程序“01 ErrorShow.exe"(在图1-2
中
列出)展示了如何获取错误代码的文本描述的方法。该应用程序的源代码和资源文件位于本书所附光盘上的01-ErrorShow目录下。一般来说,该应用程序用于显示调试程序的Watch窗口和Error Lookup程序是如何运行的。当你启动该程序时,就会出现下面这个窗口。 见原书P9的插图 你可以将任何错误代码键入该编辑控件。当你单击Look Up按钮时,在底部的滚动窗口
中
就会显示该错误的文本描述。该应用程序唯一令人感兴趣的特性是如何调用FormatMessage
函数
。下面是我使用该
函数
的方法: 见原书P10的程序(1) 第一个代码行用于从编辑控件
中
检索错误代码的号码。然后,建立一个内存块的句柄并将它初始化为NULL。FormatMessage
函数
在内部对内存块进行分配,并将它的句柄返回给我们。 当调用FormatMessage
函数
时,我传递了FORMAT_MESSAGE_FROM_SYSTEM标志。该标志告诉FormatMessage
函数
,我们想要系统定义的错误代码的字符串。我还传递了FORMAT_MESSAGE_ALLOCATE_BUFFER标志,告诉该
函数
为错误代码的文本描述分配足够大的内存块。该内存块的句柄将在hlocal变量
中
返回。第三个参数指明我们想要查找的错误代码的号码,第四个参数指明我们想要文本描述使用什么语言。 如果FormatMessage
函数
运行成功,那么错误代码的文本描述就位于内存块
中
,我将它拷贝到对话框底部的滚动窗口
中
。如果FormatMesage
函数
运行失败,我设法查看NetMsg.dll模块
中
的消息代码,以了解该错误是否与网络有关。使用NetMsg.dll模块的句柄,我再次调用FormatMessage
函数
。你会看到,每个DLL(或.exe)都有它自己的一组错误代码,你可以使用Message Compiler(MC.exe)将这组错误代码添加给该模块,并将一个资源添加给该模块。这就是Visual Studio的Error Lookup工具允许你用Modules对话框进行的操作。 图1-2 ErrorShow示例应用程序 见原书P11—16 第2章 UNICODE 随着Microsoft公司的Windows操作系统在全世界日益广泛的流行,对于我们这些软件开发人员来说,将我们的目标瞄准国际上的各个不同市场,已经成为一个越来越重要的问题。美国的软件版本比国际版本提前6个月推向市场,这曾经是个司空见惯的现象。但是,由于各国对Windows操作系统提供了越来越多的支持,因此就更加容易为国际市场生产各种应用软件,从而缩短了软件的美国版本与国际版本推出的时间间隔。 Windows操作系统始终不逾地提供各种支持,以帮助软件开发人员进行应用程序的本地化工作。应用软件可以从各种不同的
函数
中
获得特定国家的信息,并可观察控制面板的设置,以确定用户的首选项。Windows甚至支持不同的字体,以适应我们的应用的需要。 我之所以将这一章放在本书的开头,是因为我考虑到Unicode是开发任何应用程序时要采用的基本步骤。关于Unicode的问题,我在本书的每一章
中
几乎都要讲到,而且本书
中
给出的所有示例应用程序都是“用Unicode实现的”。如果你为Microsoft Windows 2000或Microsoft Windows CE开发应用程序,你应该使用Unicode进行开发。如果你为Microsoft Windows 98开发应用程序,你必须对某些问题作出决定。本章也要讲述Windows 98的有关问题。 2.1 字符集 软件的本地化要解决的真正问题,实际上就是如何来处理不同的字符集。多年来,我们许多人一直将文本串作为一系列单字节字符来进行编码,并在结尾处放上一个零。对于我们来说,这已经成了习惯。当我们调用strlen
函数
时,它在以0结尾的单字节字符数组
中
返回字符的数目。 问题是,有些文字和书写规则(比如日文
中
的汉字就是个典型的例子)的字符集
中
的符号太多了,因此单字节(它提供的符号最多不能超过256个)是根本不敷使用的。为此我们创建了双字节字符集(DBCS),以支持这些文字和书写规则。 2.1.1 单字节与双字节字符集 在双字节字符集
中
,字符串
中
的每个字符可以包含一个字节,也可以包含两个字节。例如,日文
中
的汉字,如果第一个字符在0x81与0x9F之间,或者在0xE0与0xFC之间,那么你就必须观察下一个字节,才能确定字符串
中
的这个完整的字符。如果要使用双字节字符集,对于程序员来说简直是个很大的难题,因为有些字符只有一个字节宽,而有些字符则是两个字节宽。 如果只是调用strlen
函数
,那么你无法真正了解字符串
中
究竟有多少字符,它只能告诉你到达结尾的0之前有多少个字节。ANSI的C运行期库
中
没有配备相应的
函数
,使你能够对双字节字符集进行操作。但是,Microsoft Visual C++的运行期库却包含许多
函数
,如_mbslen,它可以用来操作多字节(既包括单字节也包括双字节)字符串。 为了帮助你对DBCS字符串进行操作,Windows提供了下面的一组帮助
函数
。
函数
描述 PTSTR CharNext 返回字符串
中
的下一个字符的地址 (PCTSTR pszCurrentChar); PTSTR CharPrev 返回字符串
中
的上一个字符的地址 (PCTSTR pszStart, PCTSTR pszCurrentChar); BOOL IsDBCSLendByte 如果该字节是DBCS字符的第一个字节,则返 (BYTE bTestChar); 回TRUE 2.1.2 Unicode:宽字节字符集 Unicode是Apple和Xerox公司于1988年建立的一个技术标准。1991年,成立了一个集团机构负责Unicode的开发和推广应用。该集团由Apple、Compaq、HP、IBM、Microsoft、
Oracle
、Silicon Graphics、Sybase、Unisys和Xerox等公司组成。(若要了解该集团的全部成员,请通过网址www.Unicode.org查找。)该集团公司负责维护Unicode标准。Unicode的完整描述可以参阅AddisonWesley出版的《Unicode Standard》一书。(该书可以通过网址www.Unicode.org订购。) Unicode提供了一种简单而又一致的表示字符串的方法。Unicode字符串
中
的所有字符都是16位的字符(两个字节)。它没有专门的字节来指明下一个字节是属于同一个字符的组成部分,还是一个新字符。这意味着你只需要对指针进行递增或递减,就可以遍历字符串
中
的各个字符。你不再需要调用CharNext,CharPrev和IsDBCSLeadByte之类的
函数
。 由于Unicode用一个16位的值来表示每个字符,因此总共可以得到65000个字符,这样,它就能够对世界各国的书面文字
中
的所有字符进行编码。这远远超过了单字节字符集的256个字符的数目。 目前,已经为阿拉伯文、
中
文拼音、西里尔字母(俄文)、希腊文、西伯莱文、日文、韩文和拉丁文(英文)字母定义了Unicode代码点1。这些字符集
中
还包含了大量的标点符号、数学符号、技术符号、箭头、装饰标志、区分标志和其他许多字符。如果你将所有这些字母和符号加在一起,总计约达35000个不同的代码点,这样,总计的65000个代码点
中
,大约还有一半可供将来扩充时使用。 这65536个字符可以分成不同的区域。下面这个表显示了一部分这样的区域以及分配给这些区域的字符。 16位代码 字符 16位代码 字符 0000-007F ASCII 0300-036F 通用区分标志 0080-00FF 拉丁文1字符 0400-04FF 西里尔字母 0100-017F 欧洲拉丁文 0530-058F 亚美尼亚文 0180-01FF 扩充拉丁文 0590-05FF 西伯莱文 0250-02AF 标准拼音 0600-06FF 阿拉伯文 02B0-02FF 修改型字母 0900-097F 梵文 注1. 代码点是指字符集
中
的一个符号的位置 目前尚未分配的代码点大约还有29000个,不过它们是保留供将来使用的。另外,大约有6000个代码点是保留供你个人使用的。 2. 2 为何应该使用Unicode 当你开发应用程序时,你当然应该考虑利用Unicode的优点。即使现在你不打算对你的应用程序进行本地化,开发时将Unicode放在心上,肯定可以简化将来的代码转换工作。此外,Unicode还具备下列功能: * 可以很容易地在不同语言之间进行数据交换 * 使你能够分配支持所有语言的单个二进制.exe文件或DLL文件 * 提高你的应用程序的运行效率(本章后面还要详细介绍) 2.3 Windows 2000与Unicode Windows 2000是使用Unicode从头进行开发的,用于创建窗口、显示文本、进行字符串操作等的所有核心
函数
都需要Unicode字符串。如果你调用任何一个Windows
函数
并给它传递一个ANSI字符串,那么系统首先要将字符串转换成Unicode,然后将Unicode字符串传递给操作系统。如果你希望
函数
返回ANSI字符串,系统就会首先将Unicode字符串转换成ANSI字符串,然后将结果返回给你的应用程序。所有这些转换操作都是在你看不见的情况下发生的。当然,进行这些字符串的转换需要占用系统的时间和内存开销。 例如,如果你调用CreateWindowEx
函数
,并传递类名字和窗口标题文本的非Unicode字符串,那么CreateWindowEx必须分配内存块(在你的进程的默认堆
中
),将非Unicode字符串转换成Unicode字符串,并将结果存储在分配到的内存块
中
,然后调用Unicode版本的CreateWindowEx
函数
。 对于用字符串填入缓存的
函数
来说,系统必须首先将Unicode字符串转换成非Unicode字符串,然后你的应用程序才能处理该字符串。由于系统必须执行所有这些转换操作,因此你的应用程序需要更多的内存,并且运行的速度比较慢。通过从头开始用Unicode来开发应用程序,你就能够使你的应用程序更加有效地运行。 2. 4 Windows 98与Unicode Windows 98不是一种全新的操作系统。它继承了16位Windows操作系统的特性,它不是用来处理Unicode。如果要增加对Unicode的支持,其工作量非常大,因此在该产品的特性列表
中
没有包括这个支持项目。由于这个原因,Windows 98象它的前任产品一样,几乎都是使用ANSI字符串来进行所有的内部操作的。 你仍然可以编写用于处理Unicode字符和字符串的Windows应用程序,不过,使用Windows
函数
要难得多。例如,如果你想要调用CreateWindowEx
函数
并将ANSI字符串传递给它,这个调用的速度非常快,不需要从你进程的默认堆栈
中
分配缓存,也不需要进行字符串转换。但是,如果你想要调用CreateWindowEx
函数
并将Unicode字符串传递给它,你就必须明确分配缓存,并调用
函数
,以便执行从Unicode到ANSI字符串的转换操作。然后你可以调用CreateWindowEx,传递ANSI字符串。当CreateWindowEx
函数
返回时,你就能释放临时缓存。这比使用Windows 2000上的Unicode要麻烦得多。在本章的后面部分
中
,我要介绍如何在Windows 98下进行这些转换。 虽然Unicode
函数
的大多数代码在Windows 98
中
不起任何作用,但是有少数Unicode
函数
确实拥有非常有用的实现代码。这些
函数
是: 见原书的P21 可惜的是,这些
函数
中
有许多
函数
在Windows 98
中
会出现各种各样的错误。有些
函数
无法使用某些字体,有些
函数
会破坏内存堆栈,有些
函数
会使打印机驱动程序崩溃,如此等等。如果你要使用这些
函数
,你必须对它们进行大量的测试。即使这样,你可能仍然无法解决问题。因此你必须向用户说明这些情况。 2. 5 Windows CE与Unicode Windows CE操作系统是为小型设备开发的,这些设备的内存很小,并且不带磁盘存储器。你可能认为,由于Microsoft公司的主要目标是建立一种尽可能小的操作系统,因此它会使用ANSI作为自己的字符集。但是Microsoft公司并不是鼠目寸光。他们懂得,采用Windows CE的设备要在世界各地销售,他们希望降低软件开发成本,这样就能更加容易地开发应用程序。为此,Windows CE本身就是使用Unicode的一种操作系统。 但是,为了使Windows CE尽量做得小一些,Microsoft公司决定完全不支持ANSI Windows
函数
。因此,如果你要为Windows CE开发应用程序,你必须懂得Unicode,并且在整个应用程序
中
使用Unicode。 2. 6 需要注意的问题 下面让我们进一步明确一下“Microsoft公司对Unicode支持的情况”: * Windows 2000既支持Unicode,也支持ANSI,因此你可以为它们当
中
的任何一种开发应用程序 * Windows 98 只支持ANSI,你只能为ANSI开发应用程序 * Windows CE只支持Unicode,你只能为Unicode开发应用程序 虽然Microsoft公司试图让软件开发人员能够非常容易地开发在这3种平台上运行是软件,但是Unicode与ANSI之间的差异使得事情变得困难起来,并且这种差异通常是我遇到的最大的问题之一。请不要误解,Microsoft公司坚定地支持Unicode,并且我也坚决鼓励你使用它。不过你应该懂得,你可能遇到一些问题,需要一定的时间来解决这些问题。我建议你尽可能使用Unicode。如果你运行Windows 98,那么只有在必要时才要转换到ANSI。 不过,还有另一个小问题你应该了解,那就是COM。 2.7 对COM的简单说明 当Microsoft公司将COM从16位Windows转换成Win32时,公司作出了一个决定,即,需要字符串的所有COM接口方法都只能接受Unicode字符串。这是个了不起的决定,因为COM通常用于使不同的组件能够互相之间进行通信,而Unicode则是传递字符串的最佳手段。 如果你为Windows 2000或Windows CE开发应用程序,并且也使用COM,那么你将会如虎添翼。在你的整个源代码
中
使用Unicode,将使与操作系统进行通信和与COM
对象
进行通信的操作变成一件轻而易举的事情。 如果你为Windows 98开发应用程序,并且也使用COM,那么你将会遇到一些问题。COM要求你使用Unicode字符串。操作系统的大多数
函数
要求你使用ANSI字符串。那是多么难办的事情啊!我曾经从事过若干个项目的开发,在这些项目
中
,我编写了许多代码,仅仅是为了来回进行字符串的转换。 2. 8 如何编写Unicode源代码 Microsoft公司为Unicode设计了Windows API,这样,它可以尽量减少对你的代码的影响。实际上,你可以编写单个源代码文件,以便使用或者不使用Unicode来对它进行编译。你只需要定义两个宏(UNICODE和_UNICODE),就可以修改然后重新编译该源文件。 2. 8.1 C运行期库对Unicode的支持 为了利用Unicode字符串,因此定义了一些数据类型。标准的C头文件String.h已经作了修改,以便定义一个名字为wchar_t的数据类型,它是一个Unicode字符的数据类型: 见原书P23的程序(1) 例如,如果你想要创建一个缓存,用于存放最多为99个字符的Unicode字符串和一个结尾为零的字符,你可以使用下面这个语句: 见原书P23的程序(2) 该语句创建了一个由100个16位值组成的数组。当然,标准的C运行期字符串
函数
,如strcpy、strchr和strcat等,只能对ANSI字符串进行操作,它们不能正确地处理Unicode字符串。因此,ANSI C也拥有一组补充
函数
。图2-1显示了一些标准的ANSI C字符串
函数
,后面是它们的等价Unicode
函数
。 图2-1 标准的ANSI C字符串
函数
和它们的等价Unicode
函数
见原书P23的程序(3)和P24的程序 请注意,所有的Unicode
函数
均以wcs开头,wcs是宽字符串的英文缩写。若要调用Unicode
函数
,只需用前缀wcs来取代任何ANSI字符串
函数
的前缀str即可。 说明 大多数软件开发人员可能已经不记得这样一个非常重要的问题了,那就 是Microsoft公司提供的C运行期库与ANSI的标准C运行期库是一致的。 ANSI C规定,C运行期库支持Unicode字符和字符串。这意味着你始终都可 以调用C运行期
函数
,以便对Unicode字符和字符串进行操作,即使你是在 Windows 98上运行,也可以调用这些
函数
。换句话说,wcscat,wcslen和wcstok 等
函数
都能够在Windows 98上很好地运行,这些都是你必须关心的操作系统
函数
。 对于包含了对str
函数
或wcs
函数
进行显式调用的代码来说,你无法非常容易地同时为ANSI和Unicode对这些代码进行编译。在本章前面部分的内容
中
,我说过可以创建同时为ANSI和Unicode进行编译的单个源代码文件。若要建立这种双重功能,你必须包含Tchar.h文件,而不是包含String.h文件。 Tchar.h文件的唯一作用是帮助你创建ANSI/Unicode通用源代码文件。它包含你应该用在源代码
中
的一组宏,而不应该直接调用str
函数
或者wcs
函数
。如果你在编译源代码文件时定义了_UNICODE,这些宏就会引用wcs这组
函数
。如果你没有定义_UNICODE,那么这些宏将引用str这组宏。 例如,在Tchar.h
中
有一个宏称为_tcscpy。如果在你包含该头文件时没有定义_UNICODE,那么_tcscpy就会扩展为ANSI的strcpy
函数
。但是如果定义了_UNICODE,_tcscpy将扩展为Unicode的wcscpy
函数
。拥有字符串参数的所有C运行期
函数
都在Tchar.h文件
中
定义了一个通用宏。如果你使用通用宏,而不是ANSI/Unicode的特定
函数
名,你就能够顺利地创建可以为ANSI或Unicode进行编译的源代码。 但是,除了使用这些宏之外,还有一些操作你是必须进行的。Tchar.h文件包含了一些其他的宏。 若要定义一个ANSI/Unicode通用的字符串数组,请使用下面的TCHAR数据类型。如果定义了_UNICODE,TCHAR将声明为下面的形式: 见原书P25的程序(1) 如果没有定义_UNICODE,则TCHAR将声明为下面的形式: 见原书P25的程序(2) 使用该数据类型,你可以象下面这样分配一个字符串: 见原书P25的程序(3) 你也可以创建对字符串的指针: 见原书P25的程序(4) 不过上面这行代码存在一个问题。按照默认设置,Microsoft公司的C++编译器能够编译所有的字符串,就象它们是ANSI字符串,而不是Unicode字符串。因此,如果没有定义_UNICODE,该编译器将能正确地编译这一行代码。但是,如果定义了_UNICODE,就会产生一个错误。若要生成一个Unicode字符串而不是ANSI字符串,你必须将该代码行改写为下面的样子: 见原书P25的程序(5) 原义字符串前面的大写字母L,用于告诉编译器该字符串应该作为Unicode字符串来编译。当编译器将字符串置于程序的数据部分
中
时,它在每个字符之间分散插入零字节。这种变更带来的问题是,现在只有当定义了_UNICODE时,程序才能成功地进行编译。我们需要另一个宏,以便有选择地在原义字符串的前面加上大写字母L。这项工作由_TEXT宏来完成,_TEXT宏也在Tchar.h文件
中
做了定义。如果定义了_UNICODE,那么_TEXT定义为下面的形式: 见原书P25的程序(6)
oracle
存储过程
失效,
Oracle
中
重新编译
无效
的
存储过程
, 或
函数
、触发器等
对象
Oracle
中
的
存储过程
在有些情况下会变成失效状态,在 PL/SQL Developer
中
该
存储过程
的图标左上角显示一把小红叉叉。比如储过程所引用的
对象
失效,dblink 出问题啦都可能引起用到它的
存储过程
失效。再就我的
存储过程
经常会变成
无效
,至今原因都未查明。查询 dba_dependencies 视图可以看到
存储过程
所引用的
对象
,再就在 dba_objects 视图
中
可以看到
对象
的 cre...
赵强老师:
Oracle
数据库从10g到11g(5)过程、
函数
和触发器
学习并掌握使用PL/SQL程序开发
Oracle
数据库的
存储过程
、存储
函数
和触发器;并掌握如何在Java程序
中
调用
存储过程
、存储
函数
。
oracle
提示
存储过程
无效
,
Oracle
认证 :
Oracle
中
重新编译
无效
的
存储过程
,或
函数
、触发器...
Oracle
中
的
存储过程
在有些情况下会变成失效状态,在PL/SQL Developer
中
该
存储过程
的图标左上角显示一把小红叉叉。比如储过程所引用的
对象
失效,dblink出问题啦都可能引起用到它的
存储过程
失效。再就我的
存储过程
经常会变成
无效
,至今原因都未查明。查询dba_dependencies视图可以看到
存储过程
所引用的
对象
,再就在dba_objects视图
中
可以看到
对象
的created和last...
oracle
函数
没有失效 调用时失效,
Oracle
生产
中
跑批
存储过程
或
函数
失效原因分析以及解决方案...
Oracle
生产
中
跑批
存储过程
或
函数
失效原因分析以及解决方案:报错信息: 原因分析:1.当我们编译
存储过程
或
函数
时,该过程或
函数
引用的所有
Oracle
对象
都将记录在数据字典
中
。该过程就依赖于这些存储的
对象
。我们可以看到在数据字典
中
显示了标志为非法的有编译错误的子程序。同样,如果一个DDL操作运行在其所相关的
对象
上时,存储子程序也将是非法的。当
对象
变更时,其相关的
对象
就会变成非法
对象
。如果所有的
对象
...
基础和管理
17,377
社区成员
95,128
社区内容
发帖
与我相关
我的任务
基础和管理
Oracle 基础和管理
复制链接
扫一扫
分享
社区描述
Oracle 基础和管理
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章