为什么说$ exception {"语法不正确','。"} System.Exception {System.Data.SqlClient.SqlException}

时间:2017-05-09 06:01:03

标签: c# sql sql-server asp.net-mvc entity-framework-6

  

'附近的语法不正确,'应用程序设置为运行时出现异常。

在SQL Server Management Studio中查询运行正常。但是当应用程序设置为运行时,它会抛出异常。

存储过程:

SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
GO

ALTER PROCEDURE dbo.[ USP_GET_MONTH_WISE_PENDING_DETAILS]
    @MONTH INT = 4,
    @YEAR INT = 2017
AS
BEGIN
    SET NOCOUNT ON;

    SELECT  
        P.PbsName, PC.CauseName,
        dbo.F_CONVERT_ENG_NUMBER_TO_BNG(PCI.DayFrom) + N'/' + dbo.F_CONVERT_ENG_NUMBER_TO_BNG(PCI.MonthFrom) + N'/' +
                dbo.F_CONVERT_ENG_NUMBER_TO_BNG(PCI.YearFrom) + N'থেকে' + dbo.F_CONVERT_ENG_NUMBER_TO_BNG(PCI.DayTo) + N'/' +
                dbo.F_CONVERT_ENG_NUMBER_TO_BNG(PCI.MonthTo) + N'/' + dbo.F_CONVERT_ENG_NUMBER_TO_BNG(PCI.YearTo) 'Date',
        PCI.Remarks
    FROM    
        Pbs P
    INNER JOIN 
        ProbableConnectionInfo PCI ON PCI.PbsId = P.PbsId
    INNER JOIN 
        ConnectionPendingCause CPC ON PCI.Id = CPC.ProbableConnectionId
    INNER JOIN 
        PendingCause PC ON CPC.PendingCauseId = PC.Id
    WHERE   
        PCI.MONTH = @MONTH AND
        YEAR = @YEAR AND
        CPC.PendingNumber > 0;

    SELECT  
        dbo.F_CONVERT_ENG_NUMBER_TO_BNG(SUM(IC.Pending)) 'PendingApplication',
        dbo.F_CONVERT_ENG_NUMBER_TO_BNG(SUM(IC.loadNeed)) 'AppliedLoadAmount'
    FROM    
        IndustrialConnection IC
    INNER JOIN 
        ProbableConnectionInfo PCI ON IC.ProbableConnectionId = PCI.Id
    WHERE   
        PCI.MONTH = @MONTH AND YEAR = @YEAR
    GROUP BY 
        PCI.PbsId;

    SET NOCOUNT OFF;
END;

以下是问题出现的地方:

public static DataTable GetDataByStoredProcedure(string spName, List<SqlParameter> pars = null)
{
    sqlConnection.Open();

    var sqlCommand = new SqlCommand(spName, sqlConnection);
    sqlCommand.CommandType = CommandType.StoredProcedure;

    if (pars != null)
    {
        sqlCommand.Parameters.AddRange(pars.ToArray());
    }

    var dataReader = sqlCommand.ExecuteReader();
    var dt = new DataTable("Command");
    dt.Load(dataReader);

    //sqlConnection.Close();
    return dt;
}

以下是我使用该程序的地方:

public void ShowPendingIndustrialInfo(string exportType, int year, int month)
{
    List<SqlParameter> pars = new List<SqlParameter>();

    SqlParameter p1 = new SqlParameter("@month", SqlDbType.Int);
    p1.Value = month;

    SqlParameter p2 = new SqlParameter("@year", SqlDbType.Int);
    p2.Value = year;

    pars.Add(p1);
    pars.Add(p2);

    var data = SPService.GetDataByStoredProcedure("USP_GET_MONTH_WISE_PENDING_DETAILS",pars);
    ReportHelper.ShowReport(data, exportType, "rptPendingDetails.rpt");
}

2 个答案:

答案 0 :(得分:2)

当您构建SqlCommand以运行存储过程时,您需要将CommandType属性设置为CommandType.StoredProcedure,否则,此属性的默认值为Text,并且引擎会尝试解析您的命令名称,就好像是一个文字sql命令一样。当然,名称​​ month_wise_pending_details 不是有效的sql命令文本。

  var sqlCommand = new SqlCommand(spName, sqlConnection);
  sqlCommand.CommandType = CommandType.StoredProcedure;
  var dataReader = sqlCommand.ExecuteReader();

我还应该警告你代码中的问题。您有一个全局连接对象,并且在使用它之后不会将其丢弃。这是一种不好的做法,因为ADO.NET高效地实现Connection Pooling,无需保持这些对象始终打开

public class SPService
{
    private static string connectionString = ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;

    public static DataTable GetDataByStoredProcedure(string spName)
    {
        using(SqlConnection sqlConnection = new SqlConnection(connectionString))
        using(SqlCommand sqlCommand = new SqlCommand(spName, sqlConnection))
        {
            sqlConnection.Open();
            sqlCommand.CommandType = CommandType.StoredProcedure;
            using(SqlDataReader dataReader = sqlCommand.ExecuteReader())
            {
                var dt = new DataTable("Command");
                dt.Load(dataReader);
                return dt;
             }
        }
    }
}

修改
如果要将参数传递给存储过程,则需要对代码进行一些更改:

该方法应该接收List<SqlParameter>作为第二个参数,此列表将添加到SqlCommand.Parameters集合

public static DataTable GetDataByStoredProcedure(string spName, List<SqlParameter> pars = null)
{
    using(SqlConnection sqlConnection = new SqlConnection(connectionString))
    using(SqlCommand sqlCommand = new SqlCommand(spName, sqlConnection))
    {
        sqlConnection.Open();
        sqlCommand.CommandType = CommandType.StoredProcedure;
        if(pars != null) sqlCommand.Parameters.AddRange(pars.ToArray());
        using(SqlDataReader dataReader = sqlCommand.ExecuteReader())
        {
            var dt = new DataTable("Command");
            dt.Load(dataReader);
            return dt;
         }
    }
}

调用代码更改为传递这些参数

public void ShowPendingIndustrialInfo(string exportType, int year, int month)
{
    List<SqlParameter> pars = new List<SqlParameter>();
    SqlParameter p1 = new SqlParameter("@month", SqlDbType.Int);
    p1.Value = month;
    SqlParameter p2 = new SqlParameter("@year", SqlDbType.Int);
    p2.Value = year;
    pars.Add(p1);
    pars.Add(p2);
    var data = SPService.GetDataByStoredProcedure("USP_GET_MONTH_WISE_PENDING_DETAILS", pars);
    ReportHelper.ShowReport(data, exportType, "rptPendingDetails.rpt");
}

最终编辑
关于错误未找到存储过程:如果仔细查看ALTER语句,您会注意到过程名称前面有一个空格。这也是在之前的所有修复之后仍然存在错误的原因

ALTER PROCEDURE dbo.[ USP_GET_MONTH_WISE_PENDING_DETAILS]
                     ^

答案 1 :(得分:0)

RU,

在代码中添加以下命令,通知c#sqlcommand是一个存储过程。

sqlCommand.CommandType = CommandType.StoredProcedure;

IE:

namespace PBSM.DBGateway
{
public class SPService
{
    private static string connectionString = ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;
    private static SqlConnection sqlConnection = new SqlConnection(connectionString);

    public static DataTable GetDataByStoredProcedure(string spName)
    {
        sqlConnection.Open();
        var sqlCommand = new SqlCommand(spName, sqlConnection);
        **sqlCommand.CommandType = CommandType.StoredProcedure;**
        var dataReader = sqlCommand.ExecuteReader();
        var dt = new DataTable("Command");
        dt.Load(dataReader);
        sqlConnection.Close();
        return dt;
    }
}

}

如果有帮助,请将我的回复标记为答案。问候。