使用带参数的Oracle to_date函数插入数据时触发ORA-01756错误
问题分析与解决
你的SQL拼接脚本存在两个核心问题:
1. 引号语法错误,导致SQL语句未正确终止
看你拼接的when_gave列部分:
你写的是'" + "to_date(" + gaveTime + ", 'DD/MM/YYYY'))",拼接后生成的SQL会变成类似:
Insert Into Booklets (...) values(..., 'to_date(01/01/2024, 'DD/MM/YYYY'))
这里'DD/MM/YYYY'里的第一个单引号会直接闭合前面的'to_date(01/01/2024, 的单引号,剩下的DD/MM/YYYY'))成了未被引号包裹的无效内容,直接触发ORA-01756: 引用字符串未正确终止错误。
哪怕你修正引号(比如把'DD/MM/YYYY'改成''DD/MM/YYYY''转义单引号),这种拼接方式依然风险极高。
2. 字符串拼接写法存在SQL注入风险,且日期格式处理极易出错
直接拼接控件值或用户输入到SQL语句里,是典型的SQL注入漏洞;而且如果gaveTime的格式和Oracle预期不匹配,还会触发额外的日期转换错误。
正确做法:使用参数化查询
在C#中操作Oracle数据库,应该用OracleCommand的参数化查询,不用手动拼接SQL和处理引号,同时彻底规避注入风险:
示例代码:
// 假设你已初始化OracleConnection对象conn string sql = @"Insert Into Booklets (id, exam, number_of_booklets, who_gave, when_gave, return_date) values(booklet_seq.NEXTVAL, :exam, :bookletNumbers, :whoGaveId, :gaveTime, :returnDate)"; using (OracleCommand cmd = new OracleCommand(sql, conn)) { // 添加参数,Oracle驱动自动处理类型转换 cmd.Parameters.Add(":exam", OracleDbType.Varchar2).Value = exam; cmd.Parameters.Add(":bookletNumbers", OracleDbType.Int32).Value = bookletNumbers; // 根据实际字段类型调整 cmd.Parameters.Add(":whoGaveId", OracleDbType.Varchar2).Value = whoGaveId; // 直接传入DateTime类型,无需手动转字符串 cmd.Parameters.Add(":gaveTime", OracleDbType.Date).Value = dateTimePicker1.Value; cmd.Parameters.Add(":returnDate", OracleDbType.Date).Value = ...; // 对应return_date列的实际值 conn.Open(); cmd.ExecuteNonQuery(); }
这样做的好处:
- 完全避免引号语法错误,Oracle驱动自动处理数据类型转换
- 彻底杜绝SQL注入风险
- 无需手动处理日期格式字符串,直接用
DateTime类型即可传递日期值
内容的提问来源于stack exchange,提问作者This Immortal
相关产品推荐
相关产品推荐

