为啥从应用程序调用 sql 过程返回 0 行?

Posted

技术标签:

【中文标题】为啥从应用程序调用 sql 过程返回 0 行?【英文标题】:why do sql procedure retuns 0 rows when called from applciation?为什么从应用程序调用 sql 过程返回 0 行? 【发布时间】:2019-10-21 13:35:50 【问题描述】:

我有这个程序

ALTER PROCEDURE [dbo].[ReadEquipments] null, 'Vessel'

    @Param varchar(30),    -- EquipmentNo
    @EqptType varchar(30)
AS
BEGIN

        IF((@Param is not null OR @Param != '') AND (@EqptType is not null OR @EqptType != ''))
        Begin
              select Functionallocation as 'EquipmentNo', WinFileno as 'Functionallocation', EqptType , 
              EquipmentDescription, TrainNo, PlantNo 'PlanGroup' , PlantNo 'WorkCenter' ,Area,  * from EngineeringData 
              where EqptType = @EqptType and Functionallocation = @Param
        End
        Else IF(@Param is not null OR @Param != '')
        Begin
              select Functionallocation as 'EquipmentNo', WinFileno as 'Functionallocation', EqptType , 
              EquipmentDescription, TrainNo, PlantNo 'PlanGroup' , PlantNo 'WorkCenter' ,Area,  * from EngineeringData 
              where Functionallocation = @Param
        End
        Else IF(@EqptType is not null OR @EqptType != '')
        Begin
              select Functionallocation as 'EquipmentNo', WinFileno as 'Functionallocation', EqptType , 
              EquipmentDescription, TrainNo, PlantNo 'PlanGroup' , PlantNo 'WorkCenter' ,Area,  * from EngineeringData 
              where EqptType = @EqptType
        End
        Else IF((@EqptType is null OR @EqptType = '') AND (@Param IS NOT NULL OR @Param != ''))
        Begin
              select Functionallocation as 'EquipmentNo', WinFileno as 'Functionallocation', EqptType , 
              EquipmentDescription, TrainNo, PlantNo 'PlanGroup' , PlantNo 'WorkCenter' ,Area,  * from EngineeringData 
              where FunctionalLocation = @Param
        End
        Else IF((@Param  = '' OR @Param is null) AND (@EqptType IS NOT NULL OR @EqptType != ''))
        Begin
              select Functionallocation as 'EquipmentNo', WinFileno as 'Functionallocation', EqptType , 
              EquipmentDescription, TrainNo, PlantNo 'PlanGroup' , PlantNo 'WorkCenter' ,Area,  * from EngineeringData 
              where EqptType = @EqptType
        End

END

如果我发送参数,即 null,'Vessel'。它返回 21 行。没关系,但是当我从应用程序调用时。

public DT_EquipmentResponseEquipment[] Equipments(DT_EquipmentRequest req)
    
        try
        
        if (string.IsNullOrEmpty(req.EquipmentNumberFrom))
        
            req.EquipmentNumberFrom = null;
        

        if (string.IsNullOrEmpty(req.ObjectType[0]))
        
            req.ObjectType[0] = null;
        

        SI_GetDetails_Out_SyncService c = new SI_GetDetails_Out_SyncService();


        string strConnection = System.Configuration.ConfigurationManager.ConnectionStrings["SAPConnection"].ConnectionString;

        SqlConnection con = new SqlConnection(strConnection);

        SqlCommand sqlCmd = new SqlCommand();
        sqlCmd.Connection = con;
        sqlCmd.CommandType = CommandType.StoredProcedure;
        sqlCmd.CommandText = "ReadEquipments";

        //string[] arrObjTypes = MT_EquipmentRequest.ObjectType[9];
        sqlCmd.Parameters.Add("@Param", SqlDbType.VarChar, 30).Value = null; //req.EquipmentNumberFrom;
        sqlCmd.Parameters.Add("@EqptType", SqlDbType.VarChar, 30).Value = "Vessel"; //req.ObjectType[0];

        SqlDataAdapter sqlDataAdap = new SqlDataAdapter(sqlCmd);

        DataTable dtRecord = new DataTable();
        sqlDataAdap.Fill(dtRecord);

        List<DT_EquipmentResponseEquipment> listResponse = new List<DT_EquipmentResponseEquipment>();

        foreach (DataRow dr in dtRecord.Rows)
        
            DT_EquipmentResponseEquipment response = new DT_EquipmentResponseEquipment();

            response.EQUNR = Convert.ToString(dr["EquipmentNo"]);
            response.EQTYP = Convert.ToString(dr["EqptType"]);
            response.EQKTX = Convert.ToString(dr["EquipmentDescription"]);
            response.SWERK = Convert.ToString(dr["TrainNo"]);
            response.INGRP = Convert.ToString(dr["PlanGroup"]);
            response.LGWID = Convert.ToString(dr["WorkCenter"]);
            response.HEQUI = Convert.ToString(dr["Area"]);

            listResponse.Add(response);
        



        return c.Equipment(req);
    
    catch (Exception ex)
    

        throw;
    

为此,即使我传递相同的参数,它也会返回 0 行。

sqlCmd.Parameters.Add("@Param", SqlDbType.VarChar, 30).Value = null; //req.EquipmentNumberFrom;
            sqlCmd.Parameters.Add("@EqptType", SqlDbType.VarChar, 30).Value = "Vessel"; //req.ObjectType[0];

为什么?即使是相同的参数和相同的类型,但仍然不是他们使用应用程序的结果。从原始价格来看,它返回正常。我什么都试过了。

【问题讨论】:

什么是ALTER PROCEDURE [dbo].[ReadEquipments] null, 'Vessel' “我什么都试过了。” 那么什么是“一切”呢?如果您已经尝试了所有方法,那么我们将无法为您提供任何东西。 当您将null 而不是DBNull.Value 传递给SP 时,您不会遇到异常吗? 这里要小心......你手上有性能定时炸弹。这种类型的查询会遇到难以解决的周期性和随机性能问题。查看有关此主题的这篇文章。 sqlinthewild.co.za/index.php/2009/09/15/… 另外,没什么大不了的,但您可以简化检查非空字符串和非空字符串。您可以只使用@Param > ''。另外,仔细看看你的逻辑。你有一些你无法到达的路径。第 4 和第 5 个条件不可达。 【参考方案1】:

不要将null设置为参数值,使用DBNull.Value

   sqlCmd.Parameters.Add("@Param", SqlDbType.VarChar, 30).Value = DBNull.Value; //req.EquipmentNumberFrom;

【讨论】:

以上是关于为啥从应用程序调用 sql 过程返回 0 行?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 存储过程返回 0 行

为啥我的 SQL 数据集总是返回 0 计数?

MySQL存储过程返回0行

为啥执行存储过程比脚本中的 SQL 查询更快?

如何从命令行调用 Oracle SQL 过程?

从 0jdbc6 JDBCthin 驱动程序调用具有自定义对象返回类型的 Oracle PL/SQL 过程