c# - 将 C# 对象列表中的多行数据插入 Oracle 12 数据库中的表中
问题描述
我想通过从 C#.NET 调用它的存储过程插入多行。我正在使用 Oracle 为 .NET 提供的 OracleDataAccess.dll 非托管 .net 驱动程序并使用 VS 2015。我的程序是一个控制台程序,它将读取 excel 文件(一个接一个)查看 excel 中的特定工作表并插入来自在 oracle 中将工作表放入表中。
我研究过,发现有人说可以通过 XML、UDT 和 OracleBulkCopy 完成,但我发现的代码不起作用。我尝试通过将其作为 xml 代码行运行来对其进行测试。最后提供了此错误的屏幕转储。
我正在寻找有关如何将其从 C# 传递到 Oracle 以实现将这些记录插入 Oracle 表的结果的解决方案。如果您能帮助我在 Oracle 和 C#.NET 上解决这个问题,我将不胜感激。
C#.NET 端代码如下:
public class DSelect
{
public string Installation { get; set; }
public int Account { get; set; }
public int BusinessNumber { get; set; }
public long Sysd { get; set; }
public decimal LocX { get; set; }
public string Type { get; set; }
public string Wattage { get; set; }
public decimal ALen { get; set; }
public int LWatt { get; set; }
public string Tempr { get; set; }
public DateTime CreatedDate { get; set; }
}
List<DSelect> listDSelect = new List<DSelect>();
.... Reading an excel worksheet row in a loop and building my list. There can be between 500 to 1000 rows of data in the worksheet
var deSel= new DSelect();
deSel.Installation = "install1";
.................................
listDSelect.Add(deSel)
XmlSerializer serializer = new XmlSerializer(typeof(List<DSelect>));
var stringwriter = new System.IO.StringWriter();
serializer.Serialize(stringwriter, listDSelect);
传递给存储过程以插入到 Oracle 数据库 12c 中的表中。
- 我想将整个列表作为对象传递给 oracle 存储过程。
- 在 oracle 存储过程中接收它并将其插入到表中。
在 SQL Developer 中失败的测试代码:
DECLARE
p_AdditionRequest varchar2(30000); -- CLOB;
t_xmlType SYS.XMLTYPE;
BEGIN
p_AdditionRequest:= '<?xml version="1.0" encoding="utf-16"?>
<ArrayOfDetailedSelection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DetailedSelection>
<Installation>645805</InstallationNumber>
<AccountNumber>33170019251</AccountNumber>
</DetailedSelection>
</ArrayOfDetailedSelection>';
--t_xmlType := sys.xmltype.createxml(p_AdditionRequest);
SELECT InstallationNumber, AccountNumber (
SELECT ExtractValue(column_value, '/DetailedSelection/InstallationNumber') InstallationNumber,
ExtractValue(column_value, '/DetailedSelection/AccountNumber') AccountNumber
FROM TABLE(XMLSequence(XMLTYPE(p_AdditionRequest).EXTRACT('/ArrayOfDetailedSelection/DetailedSelection')))
)
END;
/
解决方案
您的 SQL 代码很接近,但您有几个错误。首先,您在 Installation 和 InstallationNumber 之间不一致,其次您缺少 INTO。我创建了一个测试表来保存数据,但是这样的东西应该可以工作:
DECLARE
p_AdditionRequest varchar2(30000); -- CLOB;
BEGIN
p_AdditionRequest:= '<?xml version="1.0" encoding="utf-16"?>
<ArrayOfDetailedSelection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DetailedSelection>
<InstallationNumber>645805</InstallationNumber>
<AccountNumber>33170019251</AccountNumber>
</DetailedSelection>
</ArrayOfDetailedSelection>';
INSERT INTO TESTDETAILEDSECTION
SELECT InstallationNumber, AccountNumber
FROM (
SELECT ExtractValue(column_value, '/DetailedSelection/InstallationNumber') InstallationNumber,
ExtractValue(column_value, '/DetailedSelection/AccountNumber') AccountNumber
FROM TABLE(XMLSequence(XMLTYPE(p_AdditionRequest).EXTRACT('/ArrayOfDetailedSelection/DetailedSelection')))
);
END;
/
但是,我更喜欢对 SELECT 使用稍微不同的语法,因此:
INSERT INTO TESTDETAILEDSECTION
SELECT xt.INSTALLATION, xt.ACCOUNTNUMBER FROM
XMLTABLE('/ArrayOfDetailedSelection/DetailedSelection' PASSING xmlType(p_AdditionRequest)
COLUMNS
"INSTALLATION" varchar(20) PATH 'InstallationNumber',
"ACCOUNTNUMBER" varchar(20) PATH 'AccountNumber') xt;
后者的好处是可以在解析时设置xml中字段的数据类型。(我假设 InstallationNumber 和 AccountNumber 都是 varchars)。您的怀疑也是正确的;从 c# 传递时,您需要使用clob
. OracleDbType
这里有一个小提示,从 c# 开始,您需要将OracleDbTypeEx
参数设置为OracleDbTyp.Clob
.
推荐阅读
- database - 如何将亚马逊发电机数据库连接到反应原生应用程序
- google-cloud-firestore - 谷歌操作:从 Firestore 读取时在 BasicCard 中使用换行符
- angular - 如何在侧边栏中显示子菜单以在 Ionic 中循环显示菜单
- java - (WebView) view.setOnTouchListener 未触发
- spring-webflux - webflux单声道
onErrorReturn 未调用 - java - 从页面上的帖子中获取所有照片
- npgsql - 使用 EF Core 为 npgsql 创建架构失败
- java - 使用 JCo SAP 运行 SAP BAPI 时,getNumRows() 返回 0
- angular - Ionic 4 自定义图标无法在 Android 或 IOS 模拟器和设备上正确显示
- php - 如果查询未找到任何匹配项