【问题标题】:Insert multiple rows of data from C# List of objects into a table in Oracle 12 database将 C# 对象列表中的多行数据插入 Oracle 12 数据库中的表中
【发布时间】: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 中的表中。

  1. 我想将整个列表作为对象传递给 oracle 存储过程。
  2. 在 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;
/

【问题讨论】:

    标签: c# sql .net oracle oracle11g


    【解决方案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# 开始,您需要将 OracleDbTypeOracleDbTypeEx 的参数设置为 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
    • 乔纳森非常感谢。我会尝试一下,如果它不起作用,会通过电子邮件发送给您。晚安。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    • 2019-02-25
    • 2011-01-24
    • 2020-06-04
    相关资源
    最近更新 更多