将 C# 对象列表中的多行数据插入 Oracle 12 数据库中的表中
Posted
技术标签:
【中文标题】将 C# 对象列表中的多行数据插入 Oracle 12 数据库中的表中【英文标题】:Insert multiple rows of data from C# List of objects into a table in Oracle 12 database 【发布时间】:2020-04-08 17:19:25 【问题描述】:我想通过调用它的存储过程插入多行 来自 C#.NET。我正在使用 OracleDataAccess.dll 非托管 .net 驱动程序 由 Oracle 为 .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;
/
【问题讨论】:
【参考方案1】:您的 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
。这里有个小提示,从 c# 开始,您需要将 OracleDbType
和 OracleDbTypeEx
的参数设置为 OracleDbTyp.Clob
。
【讨论】:
乔纳森 感谢您的友好回复。我喜欢你使用 XMLTable 的想法。如果我传入更长的 XML 字符串。假设 XML 字符串中还有 500 个“DetailedSelection”部分,那么即使我将数据类型的大小增加到 varchar(100),它也会引发错误“可以绑定 LONG 值以插入 LONG 列”。跨度> 抱歉 Jonathan 更正了我之前的评论:我将类型更改为 DECLARE p_AdditionRequest CLOB; INSERT INTO TESTDETAILEDSELECTION SELECT xt.INSTALLATION, xt.ACCOUNTNUMBER FROM XMLTABLE('/ArrayOfDetailedSelection/DetailedSelection' PASSING to_clob(p_AdditionRequest) COLUMNS "INSTALLATION" varchar(100) PATH 'InstallationNumber', "ACCOUNTNUMBER" varchar(100) PATH 'AccountNumber') xt;使用 t_clob() 函数它编译得很好,但是当我运行它时,没有任何东西插入到表中。 不要使用 to_clob()。将您的 xml 声明为clob
,但您仍必须使用 PASSING xmltype(p_AdditionRequest)
。如果这不起作用,请将不起作用的 xml 发邮件给我,我会在早上再看一遍。这里已经很晚了(德国时间 21.40)。我的电子邮件是 jwillcock19@gmail.com
乔纳森非常感谢。我会尝试一下,如果它不起作用,会通过电子邮件发送给您。晚安。以上是关于将 C# 对象列表中的多行数据插入 Oracle 12 数据库中的表中的主要内容,如果未能解决你的问题,请参考以下文章