ORA-00911: invalid character 包含中文报错

本文介绍了解决SQL语句中包含中文字符时出现ORA-00911错误的方法,包括调整环境变量NLS_LANG来确保客户端与服务器端编码一致。

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

SQL在pl下正常执行在vs里报错ORA-00911: invalid character.
1.检查SQL末尾是否含有";" 去掉
2.sql包含中文报错
string sql = string.Format(@"SELECT A.TABLE_NAME   表名,
           A.COLUMN_NAME  字段名称,
           A.DATA_TYPE    字段类型,
           A.DATA_LENGTH  长度,
           A.NULLABLE     是否为空,
           A.DATA_DEFAULT 默认值,
           B.COMMENTS     注释
            FROM USER_TAB_COLUMNS A, USER_COL_COMMENTS B
            WHERE A.TABLE_NAME = B.TABLE_NAME
            AND A.COLUMN_NAME = B.COLUMN_NAME
            AND A.COLUMN_NAME = '{0}'
                ", fileid);
View Code

1
.在加载程序时候加入以下代码:一般放在Page_Load方法里边(如果这种方式不行,请选择第二种) System.Environment.SetEnvironmentVariable("NLS_LANG", "SIMPLIFIED CHINESE_CHINA.ZHS16GBK"); 2. 服务器添加环境变量(控制面板-->所有控制面板项-->系统-->高级系统设置--环境变量) --修改完成后一般需要重启机器

  变量名:NLS_LANG

 
变量名:SIMPLIFIED CHINESE_CHINA.ZHS16GBK

原因分析:客户端Oracle是非绿色或者 与服务器端Oracle不同版本,导致编码不一致,而导致错误,




 

 

转载于:https://www.cnblogs.com/-hao/p/9191767.html

<think>我们遇到了Oracle报错"ORA-00911: invalid character",这通常是因为SQL语句中包含了无效字符。在FreeSQL中,当我们使用原生SQL更新时,如果SQL语句中包含分号(;)或其他Oracle不支持的字符,就可能出现这个错误。另外,在动态字段更新中,如果字段名是Oracle的保留关键字且未用双引号包裹,也可能导致此错误。 ### 解决方案: 1. **避免分号**:在Oracle的SQL语句中,不要使用分号作为结束符(特别是在Ado.ExecuteNonQuery中)。 2. **处理保留关键字**:对于保留关键字,使用双引号包裹(注意Oracle中双引号表示区分大小写的标识符)。 3. **参数化查询**:确保使用参数化查询而不是字符串拼接。 ### 修正后的原生SQL更新方式: ```csharp string sql = $"UPDATE APPLY_TABLE SET \"{fieldName}\" = :value WHERE APPLY_ID = :id"; // 注意:这里使用双引号包裹字段名,以处理保留关键字和大小写问题 int affected = fsql.Ado.ExecuteNonQuery(sql, new OracleParameter(":value", fieldValue), new OracleParameter(":id", applyId)); ``` ### 使用SetDynamic的注意事项: `SetDynamic`方法内部会生成参数化SQL,通常不会产生无效字符问题。但要注意: - 字段名不能包含特殊字符(如空格、分号等) - 如果字段名是保留关键字,FreeSQL默认会使用`"`(双引号)包裹(在Oracle中) ### 常见错误场景及修复: 1. **SQL语句结尾有分号**: ```csharp // 错误写法(结尾有分号): string sql = $"UPDATE TABLE SET FIELD=:value WHERE ID=:id;"; // 正确写法(去掉分号): string sql = $"UPDATE TABLE SET FIELD=:value WHERE ID=:id"; ``` 2. **字段名未正确转义**: ```csharp // 错误写法(字段名为保留关键字且未转义): string sql = $"UPDATE TABLE SET ORDER = :value WHERE ID=:id"; // 正确写法(使用双引号转义): string sql = $"UPDATE TABLE SET \"ORDER\" = :value WHERE ID=:id"; ``` 3. **SQL语句中包含特殊字符**: - 确保SQL语句中不包含非必要的特殊字符(如制表符、换行符等) ### 完整修正代码(使用SetDynamic): 由于`SetDynamic`方法更安全(自动处理保留关键字和参数化),推荐优先使用: ```csharp var updateSet = new Dictionary<string, object>(); updateSet[fieldName] = fieldValue; int affected = fsql.Update<Apply>() .Where(a => a.Apply_ID == applyId) .SetDynamic(updateSet) .ExecuteAffrows(); ``` ### 调试技巧: 1. 在开发环境中启用FreeSQL的SQL日志输出: ```csharp fsql.UseMonitorCommand(cmd => { Console.WriteLine(cmd.CommandText); // 输出生成的SQL }); ``` 2. 将生成的SQL复制到Oracle客户端中执行,验证语法。 ### 最终建议: 1. **始终使用参数化查询**(无论是SetDynamic还是原生SQL) 2. **避免字符串拼接SQL**(除非绝对必要) 3. **严格验证字段名**(白名单机制) §§相关问题§§ 1. 如何在不修改代码的情况下捕获FreeSQL生成的SQL语句? 2. Oracle中哪些保留关键字最常引起ORA-00911错误? 3. 使用双引号包裹字段名会带来什么副作用? 4. 如何配置FreeSQL使其自动转义所有标识符? 5. 除了ORA-00911,还有哪些常见Oracle错误与动态SQL相关?</think>您遇到的 `ORA-00911: invalid character` 错误是 Oracle 数据库特有的常见错误,通常由以下原因引起: ### 错误原因及解决方案: 1. **SQL 语句结尾的分号问题**: ```csharp // 错误:Oracle 不允许在 SQL 语句末尾添加分号 string sql = $"UPDATE APPLY_TABLE SET {fieldName} = :value WHERE APPLY_ID = :id;"; // 正确:移除末尾分号 string sql = $"UPDATE APPLY_TABLE SET {fieldName} = :value WHERE APPLY_ID = :id"; ``` 2. **保留关键字未转义**: ```csharp // 错误:字段名是保留关键字(如 ORDER, GROUP)未转义 string sql = $"UPDATE APPLY_TABLE SET ORDER = :value WHERE APPLY_ID = :id"; // 正确:使用双引号转义保留关键字 string sql = $"UPDATE APPLY_TABLE SET \"ORDER\" = :value WHERE APPLY_ID = :id"; ``` 3. **字段名包含特殊字符**: ```csharp // 正确:使用双引号包裹所有动态字段名 string sql = $"UPDATE APPLY_TABLE SET \"{fieldName}\" = :value WHERE APPLY_ID = :id"; ``` 4. **参数化查询语法错误**: ```csharp // 正确:使用命名参数(带冒号) int affected = fsql.Ado.ExecuteNonQuery(sql, new OracleParameter("value", fieldValue), // 注意不带冒号 new OracleParameter("id", applyId)); ``` ### 完整修正代码: ```csharp [HttpPost] [Route("api/UpdateApplyField")] public IHttpActionResult UpdateApplyField() { // 获取请求数据 var json = new StreamReader(Request.InputStream).ReadToEnd(); dynamic data = JsonConvert.DeserializeObject(json); string applyId = data.Apply_ID; string fieldName = data.FieldName; object fieldValue = data.FieldValue; // 安全验证字段名 var allowedFields = new[] { "Field1", "Field2", "Status", "Amount" }; if (!allowedFields.Contains(fieldName)) { return BadRequest("非法字段更新"); } using (var fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Oracle, "your_oracle_conn_string") .Build()) { try { // 方案1:使用 SetDynamic(推荐) var updateSet = new Dictionary<string, object>(); updateSet[fieldName] = fieldValue; int affected = fsql.Update<Apply>() .Where(a => a.Apply_ID == applyId) .SetDynamic(updateSet) .ExecuteAffrows(); // 方案2:使用原生SQL(需要转义字段名) // string sql = $"UPDATE APPLY_TABLE SET \"{fieldName}\" = :value WHERE APPLY_ID = :id"; // int affected = fsql.Ado.ExecuteNonQuery(sql, // new OracleParameter("value", fieldValue), // new OracleParameter("id", applyId)); if (affected > 0) { return Ok(new { success = true }); } return Ok(new { success = false, message = "更新失败:记录不存在或未更改" }); } catch (Exception ex) { // 添加详细错误日志 Logger.Error($"Oracle更新失败: {ex.Message}\nSQL: {fssql.LastSql}"); return Ok(new { success = false, message = $"数据库错误: {ex.Message.Split('\n')[0]}" }); } } } ``` ### 关键调试技巧: 1. **捕获生成的SQL**: ```csharp // 在FreeSQL中启用SQL日志 fsql.UseMonitorCommand(cmd => { Console.WriteLine($"执行SQL: {cmd.CommandText}"); foreach (var param in cmd.Parameters) { Console.WriteLine($"参数: {param.ParameterName} = {param.Value}"); } }); ``` 2. **Oracle特殊字符处理**: - 所有保留关键字必须用双引号包裹(`"ORDER"`) - 表名和字段名区分大小写(建议统一使用大写) - 避免在SQL中使用分号 3. **常见保留关键字**: ``` ORDER, GROUP, COMMENT, LEVEL, DATE, TYPE, START, END, SELECT, TABLE, VIEW, INDEX ``` ### 最终建议: 1. **优先使用 `SetDynamic` 方法**(自动处理转义问题) 2. 所有表名和字段名在数据库中统一使用**大写** 3. 开发环境启用SQL日志记录 4. 使用Oracle SQL Developer测试生成的SQL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值