C# pl/sql 包函数

Posted

技术标签:

【中文标题】C# pl/sql 包函数【英文标题】:C# pl/sql package-function 【发布时间】:2018-01-08 14:54:27 【问题描述】:
public List<MuseumDto> GetMuseumsByName(string museum_Name)

    var connectionString = ConfigurationManager.
      ConnectionStrings["OracleConnectionString"].ConnectionString;
    var museum = new List<MuseumDto>();
    using (var connection = new OracleConnection(connectionString))
    
        OracleCommand mycom = new OracleCommand();
        connection.Open();
        mycom.CommandText = "museum_package.get_MuseumByName";
        mycom.Connection = connection;
        mycom.CommandType = CommandType.StoredProcedure;

        mycom.Parameters.Add("v_museum", museum_Name);

        OracleParameter returnParameteraram = mycom.Parameters.Add("ReturnValue", OracleDbType.RefCursor);
        returnParameteraram.Direction = ParameterDirection.ReturnValue;

        OracleDataReader reader = mycom.ExecuteReader();
        try
        
            while (reader.Read())
            
                museum.Add(new MuseumDto
                
                    museumId = reader.GetInt32(0),
                    name = reader.GetString(1),
                    city = reader.GetString(2),
                    about= reader.GetString(3),
                    schedule = reader.GetString(4),
                    noArtefacts= reader.GetInt32(5),

                );
            
        
        finally
        
            // always call Close when done reading.
            reader.Close();
        
    
    return museum;

这是表定义:

create table museum
( museumid     number(5) not null
, name         varchar2(30)
, city         varchar2(30)
, about        varchar2(200)
, schedule     varchar2(40)
, noartefacts  number(3) );

这是我的功能:

create or replace package body museum_package as

    function get_MuseumByName
        ( v_museum Museum.Name%type )
        return sys_refcursor
    is
        v_cursor sys_refcursor;
        v_museumName museum.name%type := '%' || v_museum || '%';
    begin
        open v_cursor for
            select museumID, name, city, about, schedule, noArtefacts
            from   museum 
            where  name like v_museumName;

        return v_cursor;
    end;

end museum_package;  

我收到一个异常:

ORA-06550:第 1 行,第 15 列: PLS-00306:调用“GET_MUSEUMBYNAME”时参数的数量或类型错误 ORA-06550:第 1 行,第 7 列: PL/SQL:语句被忽略

【问题讨论】:

ORA-06550 通常意味着您的 PL/sql 函数有问题。Museum.Name%type 是什么意思? @Hameed, Museum.Name%type 指示 PL/SQL 编译器将函数参数锚定到表列的数据类型,在这种情况下可能是 varchar2PLS-00306 表示函数不会使用预期的参数调用。 是一个与表中的 Museum.name 字段相同的变量,您到底在问什么? :) @Hameed @WilliamRobertson Museum.Name%type 如果我能理解,那么它是当前表列中的一个类型,但是.net 编译器如何推断类型。可能是 OP 的用户需要指定数据明确输入? @Hameed 我不懂 C#,但它似乎将 museum_Name 声明为字符串,除非还有更多内容,否则应该没问题。 【参考方案1】:

我无法在其他人的帖子中发表评论,因为我没有足够的声誉(我是新来的)。您的问题可能是因为 .NET 无法将 Oracle 中的列类型与您在读取列时指定的类型进行映射。

您能告诉我们博物馆表的列的数据类型吗?

【讨论】:

CREATE TABLE MUSEUM(MuseumId NUMBER(5) NOT NULL,NAme VARCHAR(30),CITY VARCHAR(30),关于 VARCHAR(200),SCHEDULE VARCHAR(40),NoArtefacts NUMBER(3)) ; 我注意到您的命令类型设置为 CommandType.StoredProcedure 并且您正在使用一个函数。是否有函数的命令类型?此外,您可以尝试将函数的参数类型从 Museum.Name%type 更改为 VARCHAR 来试一试。我也会尝试将函数更改为过程。 函数的存储过程也是如此,我会尝试更改它,但我认为它不会解决我的问题:( 我遇到了这个 Stack Overflow 问题。也许这正是你所需要的。 ***.com/questions/3535405/…【参考方案2】:

返回值必须作为第一个参数添加。

 OracleParameter returnParameteraram = mycom.Parameters.Add("ReturnValue", OracleDbType.RefCursor);
 returnParameteraram.Direction = ParameterDirection.ReturnValue;
mycom.Parameters.Add("v_museum", museum_Name);

【讨论】:

以上是关于C# pl/sql 包函数的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL - 如何检查是不是正在使用包/过程/函数?

远程调试 PL/SQL 包

如何在纯 C# 中使用 PL/SQL?

通过 TTS 导出 PL/SQL 包

在 pl/sql 正文包文件中获取函数和描述注释

C# 和 PL/SQL 中的加密和解密兼容性