我们有一张桌子:

CREATE TABLE ESIPARIS.T_ORDER_LINE

(
  NO           NUMBER(18),
  ORDER_NO     NUMBER(18),
  ITEM_NO      NVARCHAR2(15),
  AMOUNT       NUMBER(18,3),
  INSERT_DATE  DATE,
  INSERT_USER  NVARCHAR2(20),
  UPDATE_DATE  DATE,
  UPDATE_USER  NVARCHAR2(20),
  FLEXFIELD_1  NVARCHAR2(100),
  FLEXFIELD_2  NVARCHAR2(100),
  FLEXFIELD_3  NVARCHAR2(100),
  FLEXFIELD_4  NVARCHAR2(100)
)
TABLESPACE DEVEL
PCTUSED    0
PCTFREE    10
INITRANS   1
MAXTRANS   255
STORAGE    (
            INITIAL          64K
            NEXT             1M
            MINEXTENTS       1
            MAXEXTENTS       UNLIMITED
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
           )
NOLOGGING 
NOCOMPRESS 
NOCACHE
NOPARALLEL
MONITORING;

和对象为:

DROP TYPE ESIPARIS.ORDER_LINE_ROW;

CREATE OR REPLACE TYPE ESIPARIS.ORDER_LINE_ROW AS OBJECT
(
NO           NUMBER(18),
ORDER_NO     NUMBER(18),
ITEM_NO      NVARCHAR2(15),
AMOUNT       NUMBER(18,3),
INSERT_DATE  DATE,
INSERT_USER  NVARCHAR2(20),
UPDATE_DATE  DATE,
UPDATE_USER  NVARCHAR2(20),
FLEXFIELD_1  NVARCHAR2(100),
FLEXFIELD_2  NVARCHAR2(100),
FLEXFIELD_3  NVARCHAR2(100),
FLEXFIELD_4  NVARCHAR2(100)
)
/

CREATE OR REPLACE TYPE ESIPARIS.ORDER_LINE_TABLE as table of ESIPARIS.ORDER_LINE_ROW;
/

以及一个存储过程来处理.NET应用程序发送的对象以插入行:

CREATE OR REPLACE PROCEDURE ESIPARIS.pr_getorder_line (
   deneme   IN   order_line_table
)
IS
   err_code   NVARCHAR2 (500) := '';
   err_msg    NVARCHAR2 (500) := '';
BEGIN
   FOR i IN 1 .. deneme.COUNT
   LOOP
      INSERT INTO t_order_line
                  (NO, order_no, item_no,
                   amount, insert_date,
                   insert_user, update_date,
                   update_user, flexfield_1,
                   flexfield_2, flexfield_3,
                   flexfield_4
                  )
           VALUES (deneme (i).NO, deneme (i).order_no, nvl(deneme (i).item_no,'null geldi'),
                   nvl(deneme (i).amount,5363377869), deneme (i).insert_date,
                   deneme (i).insert_user, deneme (i).update_date,
                   deneme (i).update_user, deneme (i).flexfield_1,
                   deneme (i).flexfield_2, deneme (i).flexfield_3,
                   deneme (i).flexfield_4
                  );
   END LOOP;

   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      err_code := SQLCODE;
      err_msg := SUBSTR (SQLERRM, 1, 200);

      INSERT INTO esiparis.t_error_log
                  (event_date, event_object, MESSAGE
                  )
           VALUES (SYSDATE, err_code, err_msg
                  );
END;
/

我们创建了 udt 使用Visual Studio 2010和 odp.net 插入。我们正处于插入NVARCHAR2数据类型中的.NET应用程序发送的值。数字或日期数据类型的数据不能插入。有任何想法吗?

有帮助吗?

解决方案

您的问题可能是由于您的调用C#代码到Oracle类型(数字,日期)中的键入c#代码中的类型转换,用于将值存储在数据库中。确保UDT类使用Oracle类型,而不是.NET类型。

另外,如果您要做的就是迭代您的集合以插入记录,则应考虑使用Oracle的散装绑定功能,因为它将更加有效。看 http://dotnetslackers.com/articles/ado_net/bulkoperationsusingoracledataproviderfornetodpnet.aspx 一个很好的例子。

编辑:按照您的敬意:“我们正在寻找一个直接的SP示例。这非常适合使用绑定变量。”

无论哪种方式,您都需要正确地将类型从.NET转换为Oracle。听起来您正在做本文档中的事情:http://download.oracle.com/docs/html/e15167_01/featudts.htm#cjagfhba

EDIT2:根据您发布的答案中的代码,看来有一种更好的方法来解决该问题。

您评论了一些这样的台词:

//[07.12.2010]ISMAILH : ISNULLS ARE COMMENTED OUT FOR PROPER WORKING!
// TODO : Add code to initialise the object
//this.m_AMOUNTIsNull = true;

的目的 m_AMOUNTIsNull (或财产 AMOUNTIsNull 哪个字段)是允许代码区分实际 m_AMOUNT 设置的值是设置的,因为使用了默认的.NET值(十进制为0)。

这就是为什么在UDT填充UDT之前检查值的原因 m_AMOUNT 价值:

if ((AMOUNTIsNull == false)) {
    Oracle.DataAccess.Types.OracleUdt.SetValue(con, pUdt, "AMOUNT", this.AMOUNT);

从数据库中获取UDT时, AMOUNTIsNull 基于数据库字段是否为null:

this.AMOUNTIsNull = Oracle.DataAccess.Types.OracleUdt.IsDBNull(con, pUdt, "AMOUNT");
if ((AMOUNTIsNull == false)) {
    this.AMOUNT = ((decimal)(Oracle.DataAccess.Types.OracleUdt.GetValue(con, pUdt, "AMOUNT")));
}

但是,当您使用.NET对象并设置 AMOUNT 财产, AMOUNTIsNull 不会改变:

[OracleObjectMappingAttribute("AMOUNT")]
public decimal AMOUNT {
    get {
        return this.m_AMOUNT;
    }
    set {
        this.m_AMOUNT = value;
    }
}

如果将其更改为正确设置(并取消您已经进行的评论删除修复程序),那么您会更好,因为您既可以存储一个值并代表无效的值:

[OracleObjectMappingAttribute("AMOUNT")]
public decimal AMOUNT {
    get {
        return this.m_AMOUNT;
    }
    set {
        this.AMOUNTIsNull = false;
        this.m_AMOUNT = value;
    }
}

其他提示

在检查了Oracle ODP.NET Visual Studio插件的自动生成的类后,我们的.NET开发人员发现它在评论自动生成的代码中的某些行后正常工作,在行之后开始4行

“ // [07.12.2010] Imprh:Isnulls被评论以进行适当的工作!”。

之后,一切正常,但是我想知道这样做的更深层理由。为什么插件首先生成这些行? :

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.1
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace ESiparis {
    using System;
    using Oracle.DataAccess.Client;
    using Oracle.DataAccess.Types;
    using System.Xml.Serialization;
    using System.Xml.Schema;

    public class ORDER_LINE_ROW : INullable, IOracleCustomType, IXmlSerializable,IDisposable {

        private bool m_IsNull;
        private decimal m_AMOUNT;
        private bool m_AMOUNTIsNull;
        private System.DateTime m_UPDATE_DATE;
        private bool m_UPDATE_DATEIsNull;
        private string m_FLEXFIELD_1;
        private System.DateTime m_INSERT_DATE;
        private bool m_INSERT_DATEIsNull;
        private string m_FLEXFIELD_3;
        private string m_UPDATE_USER;
        private string m_FLEXFIELD_2;
        private decimal m_ORDER_NO;
        private bool m_ORDER_NOIsNull;
        private string m_FLEXFIELD_4;
        private string m_INSERT_USER;
        private decimal m_NO;
        private bool m_NOIsNull;
        private string m_ITEM_NO;

        public ORDER_LINE_ROW() {
            //[07.12.2010]ISMAILH : ISNULLS ARE COMMENTED OUT FOR PROPER WORKING!
            // TODO : Add code to initialise the object
            //this.m_AMOUNTIsNull = true;
            //this.m_UPDATE_DATEIsNull = true;
            //this.m_INSERT_DATEIsNull = true;
            //this.m_ORDER_NOIsNull = true;
            Dispose(false);
            this.m_NOIsNull = true;
        }

        public ORDER_LINE_ROW(string str) {
            // TODO : Add code to initialise the object based on the given string
            Dispose(false);
        }

        public virtual bool IsNull {
            get {
                return this.m_IsNull;
            }
        }

        public static ORDER_LINE_ROW Null {
            get {
                ORDER_LINE_ROW obj = new ORDER_LINE_ROW();
                obj.m_IsNull = true;
                return obj;
            }
        }

        [OracleObjectMappingAttribute("AMOUNT")]
        public decimal AMOUNT {
            get {
                return this.m_AMOUNT;
            }
            set {
                this.m_AMOUNT = value;
            }
        }

        public bool AMOUNTIsNull {
            get {
                return this.m_AMOUNTIsNull;
            }
            set {
                this.m_AMOUNTIsNull = value;
            }
        }

        [OracleObjectMappingAttribute("UPDATE_DATE")]
        public System.DateTime UPDATE_DATE {
            get {
                return this.m_UPDATE_DATE;
            }
            set {
                this.m_UPDATE_DATE = value;
            }
        }

        public bool UPDATE_DATEIsNull {
            get {
                return this.m_UPDATE_DATEIsNull;
            }
            set {
                this.m_UPDATE_DATEIsNull = value;
            }
        }

        [OracleObjectMappingAttribute("FLEXFIELD_1")]
        public string FLEXFIELD_1 {
            get {
                return this.m_FLEXFIELD_1;
            }
            set {
                this.m_FLEXFIELD_1 = value;
            }
        }

        [OracleObjectMappingAttribute("INSERT_DATE")]
        public System.DateTime INSERT_DATE {
            get {
                return this.m_INSERT_DATE;
            }
            set {
                this.m_INSERT_DATE = value;
            }
        }

        public bool INSERT_DATEIsNull {
            get {
                return this.m_INSERT_DATEIsNull;
            }
            set {
                this.m_INSERT_DATEIsNull = value;
            }
        }

        [OracleObjectMappingAttribute("FLEXFIELD_3")]
        public string FLEXFIELD_3 {
            get {
                return this.m_FLEXFIELD_3;
            }
            set {
                this.m_FLEXFIELD_3 = value;
            }
        }

        [OracleObjectMappingAttribute("UPDATE_USER")]
        public string UPDATE_USER {
            get {
                return this.m_UPDATE_USER;
            }
            set {
                this.m_UPDATE_USER = value;
            }
        }

        [OracleObjectMappingAttribute("FLEXFIELD_2")]
        public string FLEXFIELD_2 {
            get {
                return this.m_FLEXFIELD_2;
            }
            set {
                this.m_FLEXFIELD_2 = value;
            }
        }

        [OracleObjectMappingAttribute("ORDER_NO")]
        public decimal ORDER_NO {
            get {
                return this.m_ORDER_NO;
            }
            set {
                this.m_ORDER_NO = value;
            }
        }

        public bool ORDER_NOIsNull {
            get {
                return this.m_ORDER_NOIsNull;
            }
            set {
                this.m_ORDER_NOIsNull = value;
            }
        }

        [OracleObjectMappingAttribute("FLEXFIELD_4")]
        public string FLEXFIELD_4 {
            get {
                return this.m_FLEXFIELD_4;
            }
            set {
                this.m_FLEXFIELD_4 = value;
            }
        }

        [OracleObjectMappingAttribute("INSERT_USER")]
        public string INSERT_USER {
            get {
                return this.m_INSERT_USER;
            }
            set {
                this.m_INSERT_USER = value;
            }
        }

        [OracleObjectMappingAttribute("NO")]
        public decimal NO {
            get {
                return this.m_NO;
            }
            set {
                this.m_NO = value;
            }
        }

        public bool NOIsNull {
            get {
                return this.m_NOIsNull;
            }
            set {
                this.m_NOIsNull = value;
            }
        }

        [OracleObjectMappingAttribute("ITEM_NO")]
        public string ITEM_NO {
            get {
                return this.m_ITEM_NO;
            }
            set {
                this.m_ITEM_NO = value;
            }
        }

        public virtual void FromCustomObject(Oracle.DataAccess.Client.OracleConnection con, System.IntPtr pUdt) {
            if ((AMOUNTIsNull == false)) {
                Oracle.DataAccess.Types.OracleUdt.SetValue(con, pUdt, "AMOUNT", this.AMOUNT);
            }
            if ((UPDATE_DATEIsNull == false)) {
                Oracle.DataAccess.Types.OracleUdt.SetValue(con, pUdt, "UPDATE_DATE", this.UPDATE_DATE);
            }
            Oracle.DataAccess.Types.OracleUdt.SetValue(con, pUdt, "FLEXFIELD_1", this.FLEXFIELD_1);
            if ((INSERT_DATEIsNull == false)) {
                Oracle.DataAccess.Types.OracleUdt.SetValue(con, pUdt, "INSERT_DATE", this.INSERT_DATE);
            }
            Oracle.DataAccess.Types.OracleUdt.SetValue(con, pUdt, "FLEXFIELD_3", this.FLEXFIELD_3);
            Oracle.DataAccess.Types.OracleUdt.SetValue(con, pUdt, "UPDATE_USER", this.UPDATE_USER);
            Oracle.DataAccess.Types.OracleUdt.SetValue(con, pUdt, "FLEXFIELD_2", this.FLEXFIELD_2);
            if ((ORDER_NOIsNull == false)) {
                Oracle.DataAccess.Types.OracleUdt.SetValue(con, pUdt, "ORDER_NO", this.ORDER_NO);
            }
            Oracle.DataAccess.Types.OracleUdt.SetValue(con, pUdt, "FLEXFIELD_4", this.FLEXFIELD_4);
            Oracle.DataAccess.Types.OracleUdt.SetValue(con, pUdt, "INSERT_USER", this.INSERT_USER);
            if ((NOIsNull == false)) {
                Oracle.DataAccess.Types.OracleUdt.SetValue(con, pUdt, "NO", this.NO);
            }
            Oracle.DataAccess.Types.OracleUdt.SetValue(con, pUdt, "ITEM_NO", this.ITEM_NO);
        }

        public virtual void ToCustomObject(Oracle.DataAccess.Client.OracleConnection con, System.IntPtr pUdt) {
            this.AMOUNTIsNull = Oracle.DataAccess.Types.OracleUdt.IsDBNull(con, pUdt, "AMOUNT");
            if ((AMOUNTIsNull == false)) {
                this.AMOUNT = ((decimal)(Oracle.DataAccess.Types.OracleUdt.GetValue(con, pUdt, "AMOUNT")));
            }
            this.UPDATE_DATEIsNull = Oracle.DataAccess.Types.OracleUdt.IsDBNull(con, pUdt, "UPDATE_DATE");
            if ((UPDATE_DATEIsNull == false)) {
                this.UPDATE_DATE = ((System.DateTime)(Oracle.DataAccess.Types.OracleUdt.GetValue(con, pUdt, "UPDATE_DATE")));
            }
            this.FLEXFIELD_1 = ((string)(Oracle.DataAccess.Types.OracleUdt.GetValue(con, pUdt, "FLEXFIELD_1")));
            this.INSERT_DATEIsNull = Oracle.DataAccess.Types.OracleUdt.IsDBNull(con, pUdt, "INSERT_DATE");
            if ((INSERT_DATEIsNull == false)) {
                this.INSERT_DATE = ((System.DateTime)(Oracle.DataAccess.Types.OracleUdt.GetValue(con, pUdt, "INSERT_DATE")));
            }
            this.FLEXFIELD_3 = ((string)(Oracle.DataAccess.Types.OracleUdt.GetValue(con, pUdt, "FLEXFIELD_3")));
            this.UPDATE_USER = ((string)(Oracle.DataAccess.Types.OracleUdt.GetValue(con, pUdt, "UPDATE_USER")));
            this.FLEXFIELD_2 = ((string)(Oracle.DataAccess.Types.OracleUdt.GetValue(con, pUdt, "FLEXFIELD_2")));
            this.ORDER_NOIsNull = Oracle.DataAccess.Types.OracleUdt.IsDBNull(con, pUdt, "ORDER_NO");
            if ((ORDER_NOIsNull == false)) {
                this.ORDER_NO = ((decimal)(Oracle.DataAccess.Types.OracleUdt.GetValue(con, pUdt, "ORDER_NO")));
            }
            this.FLEXFIELD_4 = ((string)(Oracle.DataAccess.Types.OracleUdt.GetValue(con, pUdt, "FLEXFIELD_4")));
            this.INSERT_USER = ((string)(Oracle.DataAccess.Types.OracleUdt.GetValue(con, pUdt, "INSERT_USER")));
            this.NOIsNull = Oracle.DataAccess.Types.OracleUdt.IsDBNull(con, pUdt, "NO");
            if ((NOIsNull == false)) {
                this.NO = ((decimal)(Oracle.DataAccess.Types.OracleUdt.GetValue(con, pUdt, "NO")));
            }
            this.ITEM_NO = ((string)(Oracle.DataAccess.Types.OracleUdt.GetValue(con, pUdt, "ITEM_NO")));
        }

        public virtual void ReadXml(System.Xml.XmlReader reader) {
            // TODO : Read Serialized Xml Data
        }

        public virtual void WriteXml(System.Xml.XmlWriter writer) {
            // TODO : Serialize object to xml data
        }

        public virtual XmlSchema GetSchema() {
            // TODO : Implement GetSchema
            return null;
        }

        public override string ToString() {
            // TODO : Return a string that represents the current object
            return "";
        }

        public static ORDER_LINE_ROW Parse(string str) {
            // TODO : Add code needed to parse the string and get the object represented by the string
            return new ORDER_LINE_ROW();
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool p)
        {
            if (p == true)
            {
                GC.SuppressFinalize(this);
            }
        }
    }

    // Factory to create an object for the above class
    [OracleCustomTypeMappingAttribute("ESIPARIS.ORDER_LINE_ROW")]
    public class ORDER_LINE_ROWFactory : IOracleCustomTypeFactory ,IDisposable {

        public virtual IOracleCustomType CreateObject() {
            ORDER_LINE_ROW obj = new ORDER_LINE_ROW();
            return obj;
        }

        public void Dispose()
        {

        }
    }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top