一、问题描述
①使用navicat建模工具建立完成表结构后,导出sql语句或直接同步该模型到指定用户模式中,我们使用正常的查询语句查询内容报错【ORA-00904: "CREATETIME": 标识符无效】;
②执行插入的sql语句时报错【ORA-00913: 值过多】;
二、问题分析
2.1、ORA-00904: "CREATETIME": 标识符无效
我们检查navicat建模工具导出的建表语句,发现字段都是添加双引号的;
?
如果我们使用sql语句比如【SELECT CreateTime FROM "IQC_MaterialStandard_Record"】,就会报如下所示的错误:
?
Oracle中单引号、双引号说明
序号 | 说明 | 1 | 在Oracle中双引号的作用是: 1、【如果创建对象的时候,对象名、字段名加双引号,则表示Oracle将严格区分大小写】; 2、【否则Oracle都默认大写】 | 2 | 单引号表示:加了单引号的字段是一个字类似字符串,并不区分大小写。 单引号用于标识字符与数字的区别; 当指定字符串文本时,必须用单引号将字符串文本引住。 1-引用一个字符串常量,也就是界定一个字符串的开始和结束
select * from TEST where ID='100010'; --查询ID为100010的字符信息
select * from TEST where ID=100010; --查询JID为100010的整形数字
2-转义符,对紧随其后出现的字符(单引号)进行转义
select ' '' ' result from dual; --第二个单引号被作为转义符,第三个单引号被转义.结果为 '
select 'name''''' result from dual; --结果为name''
select 'name'||'''' result from dual; --结果为name','||' 被转义为字符拼接
| 3 | 双引号用于【关键字、对象名、字段名、别名】 双引号场景示例:
1、使用了关键字
select "sysdate" from dual; -- 等同于select sysdate from dual;
2、严格区分字段的大小写
select * from test where "ReName" = '思雨'; --双引号提示oracle严格区分大小写,rename将报错
3、使用别名
select RENAME "别名" from TEST; --别名中若有特殊字符或关键字,需要双引号包住
|
2.2、ORA-00913: 值过多
?查看我们的sql语句【 INSERT INTO "IQC_MaterialStandard_Record"("Id","InspectionLot","MaterialType") VALUES('100010','3002004101','备件','2022-06-10 13:29:36')】,仔细查看后发现是由于需插入的数据多于字段,匹配不上报的错误。
三、解决方法
3.1、解决ORA-00904: "XXX字段": 标识符无效
方法一:给字段添加上双引号在查询
//原来报错语句
SELECT CreateTime FROM "IQC_MaterialStandard_Record"
//修改后可以正常执行的语句(需要给字段添加双引号)
SELECT "CreateTime" FROM "IQC_MaterialStandard_Record"
/// <summary>
/// 串联字符串数组的所有元素,其中在每个元素之间使用指定的分隔符,在每个元素两边添加指定标识符。
/// </summary>
/// <param name="separator">分隔符(比如逗号【","】)</param>
/// <param name="fieldContainMark">字段两边包含的标识符(比如字段两边包含双引号【"\""】)</param>
/// <param name="values">需串联的数组</param>
/// <returns>返回串联字符串内容</returns>
public static string Join(String separator,string fieldContainMark, params string[] values)
{
if (string.IsNullOrEmpty(separator) || values == null || values.Length <= 0) return null;
string str = string.Empty;
int len = values.Length;
if (!string.IsNullOrEmpty(fieldContainMark))
{
for (int i = 0; i < len - 1; i++)
{
str += $"{fieldContainMark}{values[i]}{fieldContainMark}{separator}";
}
str += $"{fieldContainMark}{values[len - 1]}{fieldContainMark}";
}
else
{
for (int i = 0; i < len - 1; i++)
{
str += $"{values[i]}{separator}";
}
str += $"{values[len - 1]}";
}
return str;
}
//获取到指定模型的属性名称
var props = typeof(MaterialModel).GetProperties().Select(x => x.Name).ToArray();
//组装插入sql(获取到模型属性作为字段名称且带双引号的数组)
string cols = EntityHelper.Join(",","\"",props);
方法二:重新创建该表,去除字段上的双引号
?也可以使用其他编辑工具替换掉sql语句中的双引号,然后执行sql语句重新创建表后执行以前的语句就可以正常执行了。
3.2、解决ORA-00913: 值过多
检查sql语句发现是填充的值多于指定的字段内容,只用添加上对应的字段或删除多于的值即可,如下:
//原来的错误sql语句
INSERT INTO "IQC_MaterialStandard_Record"("Id","InspectionLot","MaterialType") VALUES('100010','3002004101','备件','2022-06-10 13:29:36')
//现在正确的sql语句(具体需要添加字段还是删除数据还需要根据自己建立的表字段查看)
INSERT INTO "IQC_MaterialStandard_Record"("Id","InspectionLot","MaterialType","CreateTime") VALUES('100010','3002004101','备件','2022-06-10 13:29:36')
|