You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SSIS执行Oracle数据库DDL脚本报错ORA-00911及错误处理需求咨询

问题分析与解决方案

一、ORA-00911错误的根本原因

你遇到的ORA-00911: invalid character错误,最可能的触发点是脚本中的非注释格式分隔线,结合SSIS的执行逻辑导致的:

看你提供的脚本开头:

-------------------------------------------------------- 
-- DDL for Table ACCOUNT 
-------------------------------------------------------- 

第一行的分隔线没有以--开头,Oracle会把这堆连续的减号当作SQL语句尝试执行,而这显然是无效的SQL语法,因此直接抛出无效字符错误。

你说脚本在数据库中能成功执行,大概率是因为你用的数据库客户端(比如PL/SQL Developer、SQL*Plus)会自动跳过这类无意义的纯符号行,或者你手动执行时无意中移除了这些行。

另外也可以排查下SSIS任务的基础配置:

  • 确认Execute SQL Task的ResultSet属性设置为None(DDL语句不会返回结果集,选其他选项会触发错误);
  • 检查脚本文件的编码,避免UTF-8带BOM的格式(部分Oracle驱动对这种编码的特殊字符兼容不好)。

解决ORA-00911的步骤

  1. 批量清理脚本注释
    把所有无--开头的分隔线改成注释格式,比如将--------------------------------------------------------替换为-- --------------------------------------------------------。如果有191个脚本,可以用Notepad++的批量替换功能(正则匹配^-{5,}$,替换为-- --------------------------------------------------------)快速处理。

  2. 修正SSIS任务配置

    • 确保Execute SQL Task的ResultSet设为None;
    • 若使用OLEDB连接,将连接管理器的RetainSameConnection设为True,提升批量执行的效率;
    • 确认SQLSourceType选择File connection,并关联Foreach循环传递的脚本文件变量。

二、配置SSIS忽略错误并记录错误脚本

要实现「跳过错误脚本、继续执行、记录错误信息」,需要从任务错误处理和日志记录两方面配置:

1. 设置Execute SQL Task的错误容错

双击Execute SQL Task,切换到Execution Options选项卡:

  • 将FailPackageOnFailure和FailParentOnFailure都设为False,这样单个脚本执行失败不会终止整个包或循环;
  • 可以把MaximumErrorCount设为一个大于191的数值,确保不会因为错误次数过多中断执行。

2. 记录错误脚本的详细信息

在Execute SQL Task的Event Handlers选项卡,添加OnError事件处理程序,用来捕获错误并记录:

方案1:用Script Task写入日志文件

假设你已经在Foreach循环中定义了变量@[User::CurrentScriptFile]存储当前脚本路径,在OnError事件的Script Task中:

  • 设置ReadWriteVariables为User::CurrentScriptFile, System::ErrorDescription;
  • 编写C#代码记录错误(示例):
using System;
using System.IO;
using Microsoft.SqlServer.Dts.Runtime;

public void Main()
{
    string scriptPath = Dts.Variables["User::CurrentScriptFile"].Value.ToString();
    string errorDetails = Dts.Variables["System::ErrorDescription"].Value.ToString();
    string logFile = @"D:\SSIS_Logs\DDL_Execution_Errors.log";
    string logContent = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 出错脚本: {scriptPath}\n错误信息: {errorDetails}\n\n";

    File.AppendAllText(logFile, logContent);
    Dts.TaskResult = (int)ScriptResults.Success;
}

方案2:用Execute SQL Task写入数据库日志表

先创建一个日志表:

CREATE TABLE DDL_EXECUTION_LOG (
    LOG_ID NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    SCRIPT_FILE VARCHAR2(500),
    ERROR_TIME TIMESTAMP DEFAULT SYSTIMESTAMP,
    ERROR_MESSAGE VARCHAR2(1000)
);

然后在OnError事件中添加Execute SQL Task,执行INSERT语句:

INSERT INTO DDL_EXECUTION_LOG (SCRIPT_FILE, ERROR_MESSAGE)
VALUES (?, ?)

将参数分别映射到@[User::CurrentScriptFile]和@[System::ErrorDescription]变量。

3. 确保Foreach循环持续执行

进入Foreach循环容器的属性设置,将MaximumErrorCount设为0(表示不限制错误次数),这样即使多个脚本失败,循环也会处理完所有191个文件。

内容的提问来源于stack exchange,提问作者MansaSeyi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 08:57:48