Oracle pragma 举例:exception_init

本文详细介绍了SQL中的PRAGMAEXCEPTION_INIT编译指令及其使用方式,包括如何为特定错误号创建异常名称,并通过EXCEPTION块进行异常处理。还提供了实例演示如何解决使用常规EXCEPTION处理无法捕获的异常问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

         PRAGMA是一个编译指示(或命令)。编译指示在编译时被处理,它们不在运行时执行。编译指示是对编译程序发出的特殊指令。它也称为伪指令(pseudoinstruction),不会改变程序的含义。它只是向编译程序传递信息 ,实际上它是非常类似于嵌在 SQL 语句的注释中的性能调整提示。
       
EXCEPTION_INIT:将一个特定的错误号与程序中所声明的异常标示符关联起来。

         示例:PRAGMA EXCEPTION_INIT(DEADLOCK_DETECTED, -60);

         EXCEPTION_INIT编译指令,即EXCEPTION的初始化。语法也简单,PRAGMA EXCEPTION (exception_name, error_number);在处理EXCEPTION 是,当没有已经定义好了的EXCEPTION NAME可用时,我们就用OTHERS来处理未被捕捉的所有的EXCEPTION,PL/SQL设计者建议大家尽量使用已知的EXCEPTION NAME来捕捉,不到最后,尽量不用这个选项,虽然不知道为什么,但估计是跟性能有关,而且编译出来的代码应该会很长。

         这个编译指令的引入也为这带来了解决方案。比如,我们要捕捉死锁这个EXCEPTION怎么办? 系统没有预定义好的EXCEPTION NAME可用。这时我们就可以用这个编译指令了。

         ora-60错误是代表死锁的意思,那我们就可以为这个错误号起一个EXCEPTION NAME,比如DEADLOCK_DETECTED,语法如下:

DECLARE
DEADLOCK_DETECTED EXCEPTION;
PRAGMA EXCEPTION_INIT(DEADLOCK_DETECTED, -60);

好我们就可以像下面一样来捕捉处理这个死锁的EXCEPTION了。

EXCEPTION
WHEN DEADLOCK_DETECTED THEN
......

这样,我们就避免了用when others then来捕捉处理这个异常了。

这个编译指令几乎可以用在所有的程序的声明项中,但要注意作用范围,另外要注意的是记住只为一个错误号起一个EXCEPTION NAME。

下面附上一段通过SQLERRM函数找出ORACLE预定义的错误号码及相应的错误信息。这在10g版本通过,在之前的版本可能会报buffer overflow错误,这是由于set serveroutput on默认为2000字节,但在10g中默认是unlimited了。

SET SERVEROUTPUT ON
SPOOL ERRORMSG.LOG
DECLARE
VMSG VARCHAR2(500);
BEGIN
FOR I IN 0..20000 LOOP
VMSG := SQLERRM(-I);
IF INSTR(VMSG,'not found') = 0 THEN
DBMS_OUTPUT.PUT_LINE(VMSG);
END IF;
END LOOP;
END;
/

SPOOL OFF

 

下面看一个例子

create or replace procedure SP_Del_Test
(P_ItemAdmin in mfitem.itemadmin%type, --ItemAdmin
 P_ItemCd    in mfitem.itemcd%type, --ItemCode
 P_Return    out number --输出参数
 ) is
  exp exception;
  PRAGMA Exception_Init(exp, -2292);
begin
  delete from mfitem t
   where t.itemcd = P_ItemCd
     and t.itemadmin = P_ItemAdmin;  --这一句会引发-2292异常,有级连删除异常
EXCEPTION
  WHEN EXP THEN
    P_Return := 9;
    ROLLBACK;
  WHEN OTHERS THEN
    ROLLBACK;
end SP_Del_Test; 

Rebuild target 'Project' compiling STC32G_GPIO.c... compiling STC32G_Delay.c... compiling STC32G_NVIC.c... compiling STC32G_UART.c... compiling STC32G_UART_Isr.c... compiling STC32G_Timer.c... compiling STC32G_Exti.c... compiling STC32G_I2C.c... compiling main.c... compiling i2c.c... compiling uart.c... compiling INA219.c... linking... *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: I2C_Init MODULE: .\i2c.obj (i2c) DEFINED: .\STC32G_I2C.obj (STC32G_I2C) *** ERROR L102: EXTERNAL ATTRIBUTE MISMATCH SYMBOL: I2C_Init MODULE: .\INA219.obj (INA219) DEFINED: .\STC32G_I2C.obj (STC32G_I2C) *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: GPIO_Inilize/STC32G_GPIO *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_ADC_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_M2M_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_LCM_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_INT0_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_INT1_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_INT2_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_INT3_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_SPI_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_INT4_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_Timer0_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_Timer1_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_Timer2_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_Timer3_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_Timer4_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_I2C_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_I2CR_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_I2CT_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_ADC_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_UART1_Rx_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_UART2_Rx_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_UART3_Rx_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_UART1_Tx_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_UART4_Rx_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_UART2_Tx_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_UART3_Tx_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_CAN_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_DMA_UART4_Tx_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_LCM_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_CMP_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_LIN_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_RTC_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_SPI_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_UART2_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_UART3_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_UART4_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: NVIC_PWM_Init/STC32G_NVIC *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: PrintString1/STC32G_UART *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: PrintString2/STC32G_UART *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: PrintString3/STC32G_UART *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: PrintString4/STC32G_UART *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: putchar/STC32G_UART *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: Timer_Inilize/STC32G_Timer *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: Ext_Inilize/STC32G_Exti *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: SendCmdData/STC32G_I2C *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: Get_MSBusy_Status/STC32G_I2C *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: I2C_Ack/i2c *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: I2C_Start/i2c *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: I2C_SendAck/i2c *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: I2C_SendByte/i2c *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: I2C_Stop/i2c *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: I2c_Init/i2c *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: I2C_NoAck/i2c *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: ina219_GetBusVoltage_raw/INA219 *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: ina219_GetCurrent_raw/INA219 *** ERROR L118: REFERENCE MADE TO ERRONEOUS EXTERNAL SYMBOL: I2C_Init MODULE: .\INA219.obj (INA219) ADDRESS: FF1534H Program Size: data=87.2 edata+hdata=904 xdata=0 const=26 code=6407 Target not created.
最新发布
07-18
<think>根据错误信息,主要问题有两个: 1. ERROR L104: MULTIPLE PUBLIC DEFINITIONS - 符号I2C_Init被多次定义 具体:在i2c.obj和STC32G_I2C.obj中都定义了I2C_Init函数。 2. ERROR L102: EXTERNAL ATTRIBUTE MISMATCH - 外部属性不匹配 具体:在INA219.obj中引用的I2C_Init与在STC32G_I2C.obj中定义的不匹配。 此外,还有大量未调用函数的警告(L57),这些警告表示这些函数在代码中未被使用,可以暂时忽略,但最好在最终版本中移除以减少代码大小。 解决方案: 1. 解决多重定义问题:确保I2C_Init函数只在一个地方定义。检查项目中的文件: - i2c.c 和 STC32G_I2C.c 可能都包含了I2C_Init函数的定义。 - 需要确定使用哪个I2C驱动,然后移除另一个。 2. 解决外部属性不匹配:可能是函数声明(原型)不一致导致的。检查所有文件中I2C_Init函数的声明(在头文件中)是否一致。 步骤: a) 检查i2c.h和STC32G_I2C.h(如果有)中关于I2C_Init的声明是否一致(包括函数名、参数、返回值)。 b) 确保在需要调用I2C_Init的地方,包含的头文件是同一个。 具体操作建议: 由于项目中有两个I2C驱动文件(i2c.c和STC32G_I2C.c),我们需要选择其中一个使用,并移除另一个的引用(或条件编译)。 根据错误信息,STC32G_I2C.obj中定义了I2C_Init,而i2c.obj中也定义了I2C_Init。因此,我们需要删除其中一个实现。 假设我们使用STC32G_I2C.c中的驱动,那么应该从项目中移除i2c.c(或者不编译它)。如果使用i2c.c,则移除STC32G_I2C.c。 另外,在INA219.c中调用了I2C_Init,但是链接器发现STC32G_I2C.obj中的I2C_Init与INA219.obj中引用的不一致。这可能是由于函数声明不匹配造成的。 检查STC32G_I2C.c中的I2C_Init函数定义: void I2C_Init(void) { ... } 在i2c.c中可能也有类似定义。 同时,检查头文件(如i2c.h)中是否有声明: void I2C_Init(void); 而在STC32G_I2C.h中可能声明为: void I2C_Init(void); // 应该相同 如果声明不一致(比如一个带参数,另一个不带),则会导致不匹配。 另外,注意在INA219.c中包含的头文件是否正确。应该包含定义了I2C_Init函数的头文件。 建议步骤: 1. 从项目中移除i2c.c(因为STC32G_I2C.c似乎提供了更完整的驱动,且与STC32G系列相关)。 2. 确保在main.c或INA219.c中调用I2C_Init时,包含的是STC32G_I2C.h(或者包含I2C_Init声明的头文件)。 3. 如果STC32G_I2C.h中没有声明I2C_Init,则需要添加声明。 修改示例: 在STC32G_I2C.h(如果不存在则创建)中添加: #ifndef __STC32G_I2C_H__ #define __STC32G_I2C_H__ void I2C_Init(void); #endif 然后在所有调用I2C_Init的文件中包含此头文件。 4. 如果项目不需要i2c.c,则从编译列表中移除。 5. 对于未调用的函数警告,可以忽略(如果它们确实不需要),但最好移除未使用的函数以减少代码量。 重新组织代码结构: - 只保留一个I2C驱动(STC32G_I2C.c)。 - 确保头文件中的声明与定义一致。 如果问题仍然存在,请检查是否在某个地方重复包含了头文件或者有重复的函数定义。 由于项目中有多个警告(未调用函数),这些函数占用了代码空间,建议在最终版本中移除未使用的函数。 修改后重新编译。</think>### 解决多重定义和链接错误的完整方案 您遇到的链接错误主要源于两个问题: 1. `I2C_Init` 函数在多个文件中重复定义 2. 函数声明与实际实现不匹配 以下是完整的解决方案代码: #### 1. 修改 I2C 驱动头文件(解决多重定义) ```c /* i2c.h - 添加条件编译防止多重包含 */ #ifndef __I2C_H__ #define __I2C_H__ // 统一函数声明 void I2C_Init(void); void I2C_WriteNbyte(u8 addr, u8 *p, u8 number); void I2C_ReadNbyte(u8 addr, u8 *p, u8 number); #endif ``` #### 2. 修改 STC32G_I2C.c(解决多重定义) ```c /* STC32G_I2C.c - 移除重复的I2C_Init实现 */ #include "STC32G_I2C.h" // 注释掉或删除以下函数(已在i2c.c中实现) /* void I2C_Init(void) { // 原实现内容... } */ // 保留其他特定于STC32G的I2C功能函数 void STC32G_I2C_SpecialFunction(void) { // 特定于芯片的功能实现 } ``` #### 3. 修改 INA219.c(解决外部属性不匹配) ```c /* INA219.c - 确保包含正确的头文件 */ #include "INA219.h" #include "i2c.h" // 统一使用i2c.h头文件 // 保持原有的INA219函数实现不变 void ina219_Write_Register(u8 reg, u16 dat) { // 原有实现... } // 其他INA219函数... ``` #### 4. 修改 main.c(确保正确初始化顺序) ```c /* main.c */ #include "STC32G_I2C.h" #include "i2c.h" // 包含统一的I2C头文件 #include "INA219.h" int main(void) { // 初始化顺序 I2C_Init(); // 使用统一的I2C初始化 INA219_Init(); // 初始化INA219传感器 while(1) { // 读取传感器数据 u16 voltage = INA219_ReadBusVoltage(); s16 current = INA219_ReadCurrent(); // 处理并显示数据... } } ``` #### 5. 项目文件结构调整建议 ```diff 项目目录结构: ├── Drivers/ │ ├── STC32G/ │ │ ├── STC32G_I2C.c // 只包含芯片特定功能 │ │ └── STC32G_I2C.h │ └── Peripherals/ │ ├── i2c.c // 通用I2C实现 │ └── i2c.h // 统一接口头文件 ├── Sensors/ │ ├── INA219.c │ └── INA219.h └── main.c ``` ### 错误原因及解决方案解释 #### 1. 多重定义错误 (L104) ```c *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: I2C_Init MODULE: .\i2c.obj (i2c) DEFINED: .\STC32G_I2C.obj (STC32G_I2C) ``` **原因**:`I2C_Init` 函数在 `i2c.c` 和 `STC32G_I2C.c` 中都有实现 **解决**: - 保留一个实现(通常保留通用 `i2c.c` 中的实现) - 从 `STC32G_I2C.c` 中移除重复的函数定义 #### 2. 外部属性不匹配错误 (L102) ```c *** ERROR L102: EXTERNAL ATTRIBUTE MISMATCH SYMBOL: I2C_Init MODULE: .\INA219.obj (INA219) DEFINED: .\STC32G_I2C.obj (STC32G_I2C) ``` **原因**:函数声明(头文件)与实际实现不匹配 **解决**: - 创建统一的 `i2c.h` 头文件 - 所有文件包含同一个头文件确保声明一致 #### 3. 未调用函数警告 (L57) ```c *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS NAME: I2C_Ack/i2c ``` **原因**:代码中存在未被调用的函数 **解决策略**: 1. 对于库函数:保留但添加 `#pragma disable` 指令 2. 对于未使用的自定义函数:移除或条件编译 ```c /* 在i2c.c中添加 */ #pragma disable(I2C_Ack) // 禁用未调用函数的警告 #pragma disable(I2C_Start) #pragma disable(I2C_SendAck) // ...其他未调用函数 ``` ### 优化后的I2C初始化实现 ```c /* i2c.c - 统一实现 */ #include "i2c.h" // 实际I2C初始化实现 void I2C_Init(void) { // 1. 配置I2C时钟 I2CCLK = 0x20; // 设置I2C时钟频率 // 2. 配置GPIO为I2C功能 P_SW2 |= 0x04; // 选择I2C引脚 // 3. 使能I2C控制器 I2CCON = 0x40; // 使能I2C接口 // 4. 设置超时和中断 I2CSTAT = 0x00; // 清除状态标志 } // 其他I2C函数实现... ``` ### 最终项目配置文件建议 ```makefile # Keil项目配置建议 TARGET = YourProjectName # 源文件列表(避免重复) SRC = main.c \ Drivers/Peripherals/i2c.c \ Drivers/STC32G/STC32G_I2C.c \ Sensors/INA219.c \ # 其他必要文件... # 头文件路径 INC = Drviers/Peripherals \ Drivers/STC32G \ Sensors ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值