zoukankan      html  css  js  c++  java
  • 调用EF的存储过程报“存储区数据提供程序返回的数据读取器所具有的列数对于所请求的查询不够”问题

    最近使用EF的函数导入(设置映射的存储过程)遇到该问题。从错误描述很难知道问题发生在哪里?一遍又一遍核对了代码的参数名称和存储过程的参数名称是否一致,也使用SQL探查器跟到执行的sql语句都正常返回结果。

    存储过程简要说明如下(代码一):


    CREATE PROCEDURE [dbo].[pmsvr_ChangeBillingMode]
    (
    @in_iPhysicalRegisterId int,
    @in_bIsBillingOnline bit,
    @in_iModifiedEmployeeId int,
    @out_sErrMsg nvarchar(255) output
    )
    AS

    SET NOCOUNT ON

    ... ...
    set @out_sErrMsg = ''
    select 1 as Result
    return 1

    SET NOCOUNT OFF


    Edmx中的封装方法如下(代码二):

    public bool ChangeBillingMode(int physicalRegisterId, bool isBillingOnline, int modifiedEmployeeId, out string errMsg)
    {
    this.Connection.Open();
    EntityCommand cmd
    = ((EntityConnection)this.Connection).CreateCommand();

    cmd.CommandText
    = this.DefaultContainerName + ".ChangeBillingMode";
    cmd.CommandType
    = CommandType.StoredProcedure;

    cmd.Parameters.AddWithValue(
    "in_iPhysicalRegisterId", physicalRegisterId);
    cmd.Parameters.AddWithValue(
    "in_bIsBillingOnline", isBillingOnline);
    cmd.Parameters.AddWithValue(
    "in_iModifiedEmployeeId", modifiedEmployeeId);

    EntityParameter para2
    = new EntityParameter("out_sErrMsg", DbType.String);
    para2.Direction
    = ParameterDirection.Output;
    para2.Value
    = string.Empty;
    cmd.Parameters.Add(para2);

    EntityParameter ret
    = new EntityParameter("ReturnValue", DbType.Int32);
    ret.Direction
    = ParameterDirection.ReturnValue;
    ret.Value
    = 0;
    cmd.Parameters.Add(ret);

    cmd.ExecuteNonQuery();

    errMsg
    = cmd.Parameters["out_sErrMsg"].Value.ToString();
    int returnValue = (int)cmd.Parameters["ReturnValue"].Value;
    return (returnValue > 0);
    }

    最后发现在添加函数导入时指定了返回类型为标量Boolean,而当时我理所当然的认为该返回类型是指存储过程最后的Return语句的返回值类型(就这样设置了,因为成功Return 1,失败Return 0);下面是添加函数导入画面(图1):

    当时存储过程代码(参见代码一)没有Select 1 as Result这句的,所以总是报如下错误:

    后来在Return前增加了上述Select语句就OK,至此才明白添加函数导入的返回类型是指最后一个SELECT语句的字段类型(仅返回一个字段的情况);所以如果没有使用SELECT语句返回则应该置返回类型为“无”;如果SELECT多个字段或者数据表行时必须将返回类型指定为“实体”(即DTO类型);如果是表就必须建一个对应的DTO;如果返回若干字段则必须为这些字段手工创建DTO类型。如果是返回DTO类型的则无需在分部类封装方法了,直接使用导入的函数即可。

    总结:如果不使用最后SELECT结果的话,则不必理会返回类型,将返回类型设置为“无”即可,当然我们封装的函数可以获取存储过程Return结果及OUTPUT类型的参数。所以上面例子代码可以删除存储过程中的Return前的Select语句,同时添加函数导入时指定返回类型为“无”。

  • 相关阅读:
    Linux NFS 和 Samba 共享配置
    ORA00600 internal error code, arguments [%s] [%s] [%s] [keltnfyldmInit] [46] [1] 错误的解决方法
    Linux 平台下 RMAN 全备 和 增量备份 shell 脚本
    dba_tables 和 dba_segments 表中 blocks 的区别
    RMAN 同机复制数据库
    如何 搭建 RMAN 备份平台
    RMAN 系列(五) RMAN 还原 与 恢复
    dba_tables 和 dba_segments 表中 blocks 的区别
    用RMAN复制 搭建 物理 Data Gurad 环境
    企业管理器(OEM)介绍: Grid Control 和 Database Control
  • 原文地址:https://www.cnblogs.com/chriskwok/p/1804358.html
Copyright © 2011-2022 走看看