Oracle存儲過程(Stored Procedure)使用自定義類實體參數


如何在Oracle存儲過程使用自定義類實體參數呢?

語言:C#

1.首先新建表、Sequence、存儲過程、以及Oracle自定義Type

--新建dog表
create table tbl_dog
(
id number,
DogName nvarchar2(20),
DogColor nvarchar2(20),
DogAge number
);
--為dog表新建sequence為ID使用
create sequence seq_dog
minvalue 1
maxvalue 999999
start with 1
increment by 1
cache 50
cycle;
--新建oracle的type,與C#的Dog類對應
create or replace type dog_type as object(
       DogName nvarchar2(20),
       DogColor nvarchar2(20),
       DogAge nvarchar2(50)
);
--新建oracle的type,存放Dog類型的數組
create or replace type dog_type_array as table of dog_type;
--測試存儲過程,主要功能是將傳入的dog數組逐條寫入數據庫
create or replace procedure sp_insert_dog(dogList in dog_type_array) as
begin
  for i in 1 .. dogList.count loop 
    insert into tbl_dog(
                       id,
                       DogName,
                       DogColor,
                       DogAge
                      )
                      values
                      (
                       seq_dog.nextval,
                       dogList(i).DogName,
                       dogList(i).DogColor,
                       dogList(i).DogAge
                      );
  end loop;
end sp_insert_dog;

2.然后我們定義一個Dog類,需要實現IOracleCustomType接口(引用Oracle.DataAccess.dll)

    [DataContract]
    public class Dog : IOracleCustomType
    {
        [DataMember]
        [OracleObjectMappingAttribute("DOGNAME")]
        public string DogName { get; set; }
        [DataMember]
        [OracleObjectMappingAttribute("DOGCOLOR")]
        public string DogColor { get; set; }
        [DataMember]
        [OracleObjectMappingAttribute("DOGAGE")]
        public Int64 DogAge { get; set; }

        #region IOracleCustomType Members
        public void FromCustomObject(Oracle.DataAccess.Client.OracleConnection con, IntPtr pUdt)
        {
            OracleUdt.SetValue(con, pUdt, "DOGNAME", DogName);
            OracleUdt.SetValue(con, pUdt, "DOGCOLOR", DogColor);
            OracleUdt.SetValue(con, pUdt, "DOGAGE", DogAge);
        }

        public void ToCustomObject(Oracle.DataAccess.Client.OracleConnection con, IntPtr pUdt)
        {
            DogName = (String)OracleUdt.GetValue(con, pUdt, "DOGNAME");
            DogColor = (String)OracleUdt.GetValue(con, pUdt, "DOGCOLOR");
            DogAge = (Int64)OracleUdt.GetValue(con, pUdt, "DOGAGE");
        }

        #endregion
    }

    [OracleCustomTypeMappingAttribute("DOG_TYPE")]
    public class DogFactory : IOracleCustomTypeFactory
    {
        public IOracleCustomType CreateObject()
        {
            return new Dog();
        }
    }

    [OracleCustomTypeMappingAttribute("DOG_TYPE_ARRAY")]
    public class DogListFactory : IOracleArrayTypeFactory
    {
        public Array CreateArray(int numElems)
        {
            return new Dog[numElems];
        }
        public Array CreateStatusArray(int numElems)
        {
            return null;
        }
    }

3.執行存儲過程的函數

    public class ExcuteStoreProcedure
    {
        public static int ExecuteDogs(List<Dog> dogList)
        {
            try
            {
                const string conn = @"此處為Oracle鏈接字符串";
                using (var oc = new Oracle.DataAccess.Client.OracleConnection(conn))
                {
                    oc.Open();
                    Oracle.DataAccess.Client.OracleCommand cmd = oc.CreateCommand();
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.CommandText = "SP_INSERT_DOG";

                    var p1 = new Oracle.DataAccess.Client.OracleParameter
                    {
                        OracleDbType = Oracle.DataAccess.Client.OracleDbType.Array,
                        Direction = ParameterDirection.Input,
                        UdtTypeName = "DOG_TYPE_ARRAY"
                    };
                    if (dogList != null)
                    {
                        p1.Value = dogList.ToArray();
                    }
                    cmd.Parameters.Add(p1);
                    return cmd.ExecuteNonQuery();
                }
            }
            catch (Exception)
            {
                return -1;
            }
        }
    }

4.執行入口

        private static void Main()
        {
            var dogs = new List<Dog>
            {
                new Dog {DogAge = 1, DogColor = "Red", DogName = "紅牛"},
                new Dog {DogAge = 2, DogColor = "Black", DogName = "黑旋風"},
                new Dog {DogAge = 3, DogColor = "Green", DogName = "綠帽子"},
                new Dog {DogAge = 4, DogColor = "White", DogName = "白鶴"},
                new Dog {DogAge = 5, DogColor = "Blue", DogName = "布魯"},
                new Dog {DogAge = 6, DogColor = "Yellow", DogName = "皇帝"}
            };
            ExcuteStoreProcedure.ExecuteDogs(dogs);
        }

5.看一下執行結果,可以看到數據已經插進去了。

6.那么如何使用PL/SQL Developer調試這種參數的存儲過程呢?

很簡單,可以參考下面SQL代碼:

declare
  -- Non-scalar parameters require additional processing 
  doglist dog_type_array:= dog_type_array(dog_type('一黑','Black',8),
  dog_type('二黑','Black',8),
  dog_type('三黑','Black',8),
  dog_type('四黑','Black',8));
begin
  -- Call the procedure
  sp_insert_dog(doglist => doglist);
end;

執行一下,數據入庫。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM