【问题标题】:TSQL create a stored procedure using c#TSQL使用c#创建存储过程
【发布时间】:2016-12-04 20:06:04
【问题描述】:

我正在尝试在我的 .net 项目中创建一个程序(删除一个程序并用新数据重新制作它)。当我在数据库“创建新查询”中运行相同的查询时,它工作正常,但是当我尝试在 c# 中运行它时,它给了我一个错误。

private void makeprocedure()
            {
                string sqlProcedureCreate = @"
    IF(OBJECT_ID('usp_HourData') IS NOT NULL)
        DROP PROCEDURE IF EXISTS usp_HourData;
    GO

    CREATE PROCEDURE usp_HourData
    AS
    BEGIN

    SELECT Employee.[First Name] + ' ' + Employee.[Last Name] AS 'Name',
     sum(Time.[Total Hours]) AS 'Total Hours'
     , FORMAT(Time.[Time in], 'd', 'en-gb') AS 'Worked On'
     FROM Employee
     inner join Time on
     Employee.ID ='" + getID() + "' and Time.EmployeeIdFK = '" + getID()
     + "' WHERE Time.[Time in] between '" + CalendarStart.SelectedDate + "' and '" + CalendarEnd.SelectedDate
     + @"'GROUP BY FORMAT(Time.[Time in], 'd', 'en-gb') ,Employee.[First Name] + ' ' +Employee.[Last Name];
     END     
     ";
                using (SqlCommand command = new SqlCommand(sqlProcedureCreate, con))
                {
                    command.CommandType = CommandType.Text; //I tried command.CommandType = CommandType.StoredProcedure;
                        con.Open();
                        command.ExecuteNonQuery(); //Compiler says error is on this line
                        con.Close();
                }
            }

错误在“GO”附近,必须先执行“CREATE/ALTER PROCEDURE”。

System.Data.SqlClient.SqlException was unhandled by user code
  Class=15
  ErrorCode=-2146232060
  HResult=-2146232060
  LineNumber=4
  Message=Incorrect syntax near 'GO'.
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch.
  Number=102
  Procedure=""
  Server=(LocalDB)\MSSQLLocalDB
  Source=.Net SqlClient Data Provider
  State=1
  StackTrace:
       at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
       at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
       at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
       at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
       at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
       at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
       at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
       at WebApplication2.Manager.makeprocedure() in D:\Users\Albin\MyClockIn\WebApplication2\WebApplication2\Manager.aspx.cs:line 209
       at WebApplication2.Manager.ButtonSearch_Click(Object sender, EventArgs e) in D:\Users\Albin\MyClockIn\WebApplication2\WebApplication2\Manager.aspx.cs:line 161
       at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
       at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
       at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
       at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
       at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
  InnerException: 

我该如何解决这个错误?

【问题讨论】:

  • 我猜想,你不能在 Visual Studio 中执行多个 SQL 命令。我不确定(我总是在 SSMS 中这样做),但这似乎是错误所表明的。
  • 您需要从 C# 执行此操作的原因是什么?通常这不是 DB 对象的创建方式。
  • 应该是command.ExecuteReader();
  • @Rahul - ExceuteNonQuery 是正确的命令。 ExecuteReader 是通过SqlDataReader 返回一个结果集。 OP 正在尝试在数据库中创建存储过程,而不是检索数据。
  • @Tim,是的,但从未见过有人使用应用程序代码创建 SP :)

标签: c# sql-server tsql stored-procedures


【解决方案1】:

这可能不是您问题的答案,而只是关于您的编程风格的建议。这些是您代码中的坏事:

  1. 您正在连接查询字符串。您应该使用参数。
  2. 您正在创建一个过程,其中查询包含数据而不是参数。存储过程应包含带参数的查询,您应向其传递数据。

存储过程不应该在您每次访问它们时被删除和重新创建。我可以清楚地看到只需使用 select 语句就可以达到相同的结果。如果要创建存储过程,则必须传递一些数据,否则创建存储过程毫无意义。

理论够了,让我们看看实际情况:

这是你的 MakeProcedure(请重命名)函数:

//Rename this function to some useful name
private void makeprocedure()
{
    string query = @" SELECT Employee.[First Name] + ' ' + Employee.[Last Name] AS 'Name',
sum(Time.[Total Hours]) AS 'Total Hours'
, FORMAT(Time.[Time in], 'd', 'en-gb') AS 'Worked On'
FROM Employee
inner join Time on
Employee.ID = @EmpId and Time.EmployeeIdFK = @EmpId WHERE Time.[Time in] 
between @StartDate and @EndDate GROUP BY FORMAT(Time.[Time in], 'd', 'en-gb'),
Employee.[First Name] + ' ' +Employee.[Last Name];";


    using (SqlCommand command = new SqlCommand(query, con))
    {
        command.CommandType = CommandType.Text;
        command.Parameters.AddWithValue("@EmpId", getID());
        command.Parameters.AddWithValue("@StartDate", CalendarStart.SelectedDate);
        command.Parameters.AddWithValue("@EndDate", CalendarEnd.SelectedDate);
        con.Open();
        var reader = command.ExecuteReader();
        //do something with data in the reader.
        con.Close();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    • 2016-04-04
    • 1970-01-01
    • 2011-03-21
    • 2015-05-11
    • 1970-01-01
    相关资源
    最近更新 更多