暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

如何将列表对象从C # 传递到Oracle存储过程?

ASKTOM 2019-11-08
666

问题描述

亲爱的先生们,
我知道您可能因刮胡子而感到疲倦,但是我已经在这个主题上进行了几个月的研究,但运气却很少。有没有一种方法可以将列表对象从C # 传递到存储过程?

我能够通过使用XML和多个单个数组做类似的事情,但不能使用整个列表对象。我的列表对象包含几个具有各种数据类型的字段的行。我可以在SQL Server中执行此操作,但是现在我们正在转换为Oracle,我正在尝试找到一种方法来完成此操作。

我目前正在使用以下设置:

• Visual Studio 2017
•。NET框架4.6.1
• Oracle.ManagedDataAccess 18.6.0

这是我的C # 代码:

public class Automobile
        {
            public string Make { get; set; }
            public string Model { get; set; }
            public int Year { get; set; }
            public string Country { get; set; }
        }

using Oracle.ManagedDataAccess.Client;
        using Oracle.ManagedDataAccess.Types;

        [WebMethod(EnableSession = true)]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public string InsertCars(List myCars, int userID)
        {
            DataSet dataSet = new DataSet();

            using (OracleConnection sqlConnection = new OracleConnection(OracleDBConnection))
            {
                using (OracleCommand sqlCommand = new OracleCommand("sp_InsertCars", sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCommand.CommandType = CommandType.StoredProcedure;

                    sqlCommand.Parameters.Add(
                        new OracleParameter
                        {
                            CollectionType = OracleCollectionType.PLSQLAssociativeArray,
                            Direction = ParameterDirection.Input,
                            ParameterName = "p_CarList",
                            UdtTypeName = "tt_Automobile",
                            Size = myCars.Count,
                            Value = myCars.ToArray()
                        }
                    );

                    sqlCommand.Parameters.Add(
                        new OracleParameter
                        {
                            OracleDbType = OracleDbType.Int32,
                            Direction = ParameterDirection.Input,
                            ParameterName = "p_UserID",
                            Value = userID
                        }
                    );

                    sqlCommand.Parameters.Add(
                        new OracleParameter
                        {
                            OracleDbType = OracleDbType.RefCursor,
                            Direction = ParameterDirection.Output,
                            ParameterName = "o_Cursor"
                        }
                    );

                    using (OracleDataAdapter sqlAdapter = new OracleDataAdapter(sqlCommand))
                    {
                        sqlAdapter.SelectCommand = sqlCommand;
                        sqlAdapter.Fill(dataSet);
                    }
                }

                return JsonConvert.SerializeObject(dataSet);
            }
        }


下面是我的Oracle代码:

CREATE TABLE tblCars
        (
            RecordID INT GENERATED BY DEFAULT  AS IDENTITY NOMINVALUE NOMAXVALUE INCREMENT BY 1 START WITH 1 NOCACHE NOCYCLE NOORDER,
            Make     NVARCHAR2(100)   NULL,
            Model    NVARCHAR2(100)   NULL,
            Year     INT     NULL,
            Country  NVARCHAR2(100)   NULL,
            UserID   INT              NULL
        );

        CREATE OR REPLACE TYPE ot_Automobile AS OBJECT
        ( 
            Make varchar2(100),
            Model varchar2(100),
            Year int,
            Country varchar2(100)
        );

        CREATE OR REPLACE TYPE tt_Automobile AS TABLE OF ot_Automobile;

        CREATE OR REPLACE PROCEDURE sp_InsertCars 
        (
            p_CarList In tt_Automobile,
            p_UserID In integer,
            o_Cursor Out Sys_RefCursor
        )
        AS
        BEGIN
            DBMS_Output.Enable;

            For RowItem In (Select * From Table(p_CarList))
            Loop
            Insert Into tblCars 
            (
                Make, 
                Model, 
                Year, 
                Country, 
                UserID
            )
            Values(
                RowItem.Make,
                RowItem.Model,
                RowItem.Year,
                RowItem.Country,
                p_UserID
            );        
            End Loop;

            -- Return our results after insert
            Open o_Cursor For
            Select Make, Model, Year, Country From tblCars Where UserID = p_UserID;

        EXCEPTION
            When Others Then
            DBMS_Output.Put_Line('SQL Error: ' || SQLERRM);        

        END sp_InsertCars;

        COMMIT
        /


我知道我的代码不起作用,我不是专家,但任何帮助将不胜感激。

非常感谢!

专家解答

我和我们的。Net专家对此。

对于使用用户定义类型 (UDT),您应该使用Oracle Developer Tools For Visual Studio创建自定义类。请参阅本教程的自定义类部分:
https://www.oracle.com/webfolder/technetwork/tutorials/obe/db/12c/r1/appdev/dotnet/userdefinedtypes/index.html

2) 对于使用PL/SQL表,您可能需要使用嵌套表或VARRAY,但是如果要考虑性能,则应强烈考虑更改为使用关联数组而不是用户定义的类型。

特别是,PL/SQL关联数组可从托管ODP.NET获得。UDTs目前只能由非托管ODP.NET (Oracle.DataAccess) 使用

您也可以直接在ODP.NET论坛上与我们的专家联系

https://community.oracle.com/community/groundbreakers/database/developer-tools/windows_and_.net/odp.net
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论