【问题标题】:Why saying $exception {"Incorrect syntax near ','."} System.Exception {System.Data.SqlClient.SqlException}为什么说 $exception {“',' 附近的语法不正确。”} System.Exception {System.Data.SqlClient.SqlException}
【发布时间】:2017-05-09 06:01:03
【问题描述】:

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

在 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");
}

【问题讨论】:

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


    【解决方案1】:

    当您构建 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&lt;SqlParameter&gt; 作为第二个参数,此列表将添加到 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]
                         ^
    

    【讨论】:

    • 我注意到您已经更改了sp的名称。现在它读作 USP_GET_MONTH_WISE_PENDING_DETAILS。哪个是正确的?你能用调试器检查传递给你的方法的参数的值是多少吗?
    • 参数作为“USP_GET_MONTH_WISE_PENDING_DETAILS4,2017”(月,年)传递给方法,我认为这是正确的。但未找到该程序。 @史蒂夫
    • 如果您的存储过程名为 USP_GET_MONTH_WISE_PENDING_DETAILS 但您通过了 USP_GET_MONTH_WISE_PENDING_DETAILS,4,2017 那么难怪数据库找不到该名称
    • 问题出在SP的名字上。您添加了月份和年份,但这使得名称不存在。我添加了代码来向您展示如何传递 SP 可选所需的参数(@mont 和 @year)。
    【解决方案2】:

    鲁,

    在代码中添加以下命令,通知 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;
        }
    }
    

    }

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

    【讨论】:

      猜你喜欢
      • 2021-03-31
      • 2019-07-17
      • 2017-12-08
      • 2014-05-09
      • 2018-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多