C# 不带参数的存储过程,用于更新数据库表

C# 不带参数的存储过程,用于更新数据库表,c#,sql-server,stored-procedures,C#,Sql Server,Stored Procedures,我有一个存储过程,它有一些参数,但我需要使用的列不是参数,我需要在日期更改时更新它,我使用的是日期选择器。我不知道如何在C中调用它,我需要使用的字段名为[completiondt] ALTER PROCEDURE [dbo].[usp_load_status_update] @id INT = 0, @statusname VARCHAR(128) = '', @loginname VARCHAR(512) AS BEGIN SET NOCOUNT ON;

我有一个存储过程,它有一些参数,但我需要使用的列不是参数,我需要在日期更改时更新它,我使用的是日期选择器。我不知道如何在C中调用它,我需要使用的字段名为
[completiondt]

ALTER PROCEDURE [dbo].[usp_load_status_update]
    @id INT = 0,
    @statusname VARCHAR(128) = '',
    @loginname VARCHAR(512)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @today DATETIME = [dbo].[fnc_getdatelocal]()
    DECLARE @statusid INT
    DECLARE @oldstatusid INT
    DECLARE @olddriverid INT

    SELECT @statusid = [id] 
    FROM [LoadStatus] 
    WHERE [name] = @statusname

    SELECT @oldstatusid = [statusid], @olddriverid = [driverid] 
    FROM [Load] 
    WHERE [id] = @id

    -- update status, and reset driverid to null if it is back to pending
    UPDATE [Load] 
    SET [statusid] = ISNULL(@statusid, 0),
        [driverid] = CASE 
                        WHEN ISNULL(@statusid, 0) = 0 
                           THEN NULL
                           ELSE [driverid] 
                     END
    WHERE [id] = @id

    --kludge for now, need to update status on each row in the future
    UPDATE [LoadContact] 
    SET [statusid] = IsNull(@statusid, 0),
        [completiondt] = CASE
                            WHEN [instancetype] = 1 
                                 AND ISNULL(@oldstatusid, 0) < 3 
                                 AND ISNULL(@statusid, 0) >= 3 
                               THEN @today
                            WHEN [instancetype] = 2 
                                 AND ISNULL(@oldstatusid, 0) < 4 
                                 AND ISNULL(@statusid, 0) >= 4 
                               THEN @today
                            ELSE [completiondt]
                         END
    WHERE [loadid] = @id

    --kludge for now, need to update order invoice status separately
    IF (ISNULL(@statusid, 0) >= 8)
    BEGIN
        UPDATE [Invoice] 
        SET [statusid] = 8
        WHERE [orderid] = @id

        UPDATE [Bill] 
        SET [statusid] = 8
        WHERE [loadid] = @id
    END

一旦我弄明白这一点,它将等于
currentDate

我将尝试回答您的问题,这是否适用于您取决于您的最终目标和应用程序需求

protected void editDeliveredDate_DateChanged(object sender, EventArgs e)
{
    ASPxDateEdit dateEdit = sender as ASPxDateEdit;
    // I made your currentDate variable to be nullable
    DateTime? currentDate = dateEdit.Date; 

    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ACAOSBConnectionString"].ToString()))
    {
        string ordstr = (txt_orderid.Text != null) ? txt_orderid.Text : string.Empty;
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = conn;
        cmd.CommandText = "usp_load_status_update";
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.Add("@id", SqlDbType.Int).Value = ordstr.ToString();
        cmd.Parameters.Add("@loginname", SqlDbType.VarChar, 512).Value = Page.User.Identity.Name;
        if(currentDate != null)
        { 
            // only set the parameter if it's not null, this will allow the SQL sproc to use its existing logic        
            cmd.Parameters.Add("@datecompleted", SqlDbType.DateTime).Value = currentDate;
        }

        try
        {
            conn.Open();
            cmd.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            //TODO: save log for now;
            int ex_errorid = 0;
            string ex_msg = string.Concat((ex != null && ex.Message != null) ? ex.Message.ToString() : (ex != null && ex.InnerException != null) ? ex.InnerException.ToString() : "No Message Found ", (ex != null && ex.StackTrace != null) ? ex.StackTrace.ToString() : "No Strack Trace ");
            int ex_genericid = 0;
            string ex_username = (Page != null && Page.User != null && Page.User.Identity != null && Page.User.Identity.Name != null) ? Page.User.Identity.Name : "No user found";
            Jobs.log_somewhere ex_errorlog = new Jobs.log_somewhere();
            ex_errorlog.log_secos_error(ex_errorid, ex_msg, ex_genericid, ex_username);
        }
    }
}
注释已添加到我所做更改的代码中


首先,我添加了一个新的SQL参数
@datecompleted
,默认值为NULL。这将允许您在从C#调用存储过程时排除它,并在必要时继续使用现有的SQL逻辑

其次,我添加了一个
COALESCE
调用,如果
@datecompleted
值不为NULL,则使用该值;如果函数为NULL,则调用函数
fnc\u getdatelocal

SQL:


我不理解这个问题,因为您发布的代码似乎已经有了一个示例。我不确定如何调用[completiondt],因为它不是一个参数,我需要使用存储过程中的
@Id
将该参数更新为SQL,根据表定义中的SQL字段类型,根据需要的类型设置此新参数的SQL类型,更新SQL
update
语句以设置此值。在C#中添加参数,再次使用C#中的
@Id
参数作为示例,并根据您在存储过程中键入SQL参数的方式设置类型。我认为这里的底线是您需要能够修改SQL过程。你能做到吗?因为听起来你并不是出于某种原因在考虑这个问题。你不需要叫专栏。您可以使用update语句对其进行更新,该语句应包含where子句,以将更新限制在某些行。有点像您已经拥有的所有其他更新语句。我不确定这里的问题到底是什么。
ALTER PROCEDURE [dbo].[usp_load_status_update]
    @id INT = 0,
    @statusname VARCHAR(128) = '',
    @loginname VARCHAR(512),
    @datecompleted DATETIME = NULL -- Added new SQL parameter for date completed input from C#
AS
BEGIN
    SET NOCOUNT ON;

    -- Set the @today variable to use the @datecompleted paramter if it's not null otherwise use date from the fnc_getdatelocal() function
    DECLARE @today DATETIME = COALESCE(@datecompleted,[dbo].[fnc_getdatelocal]())
    -- Depending on the locality of the @datecompleted parameter and your application's requirements, 
    --   you will need to figure out the best way for your process to convert to locality used by the fnc_getdatelocal function
    -- Does your function accept a parameter, if so you may be able to pass the @datecompleted parameter to it, e.g.  DECLARE @today DATETIME = COALESCE(@datecompleted,[dbo].[fnc_getdatelocal](@datecompleted))

    DECLARE @statusid INT
    DECLARE @oldstatusid INT
    DECLARE @olddriverid INT

    SELECT @statusid = [id] 
    FROM [LoadStatus] 
    WHERE [name] = @statusname

    SELECT @oldstatusid = [statusid], @olddriverid = [driverid] 
    FROM [Load] 
    WHERE [id] = @id

    -- update status, and reset driverid to null if it is back to pending
    UPDATE [Load] 
    SET [statusid] = ISNULL(@statusid, 0),
        [driverid] = CASE 
                        WHEN ISNULL(@statusid, 0) = 0 
                           THEN NULL
                           ELSE [driverid] 
                     END
    WHERE [id] = @id

    --kludge for now, need to update status on each row in the future
    UPDATE [LoadContact] 
    SET [statusid] = IsNull(@statusid, 0),
    [completiondt] = CASE
                        WHEN [instancetype] = 1 
                             AND ISNULL(@oldstatusid, 0) < 3 
                             AND ISNULL(@statusid, 0) >= 3 
                           THEN @today
                        WHEN [instancetype] = 2 
                             AND ISNULL(@oldstatusid, 0) < 4 
                             AND ISNULL(@statusid, 0) >= 4 
                           THEN @today
                        ELSE [completiondt]
                     END
    WHERE [loadid] = @id

    --kludge for now, need to update order invoice status separately
    IF (ISNULL(@statusid, 0) >= 8)
    BEGIN
        UPDATE [Invoice] 
        SET [statusid] = 8
        WHERE [orderid] = @id

        UPDATE [Bill] 
        SET [statusid] = 8
        WHERE [loadid] = @id
    END
protected void editDeliveredDate_DateChanged(object sender, EventArgs e)
{
    ASPxDateEdit dateEdit = sender as ASPxDateEdit;
    // I made your currentDate variable to be nullable
    DateTime? currentDate = dateEdit.Date; 

    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ACAOSBConnectionString"].ToString()))
    {
        string ordstr = (txt_orderid.Text != null) ? txt_orderid.Text : string.Empty;
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = conn;
        cmd.CommandText = "usp_load_status_update";
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.Add("@id", SqlDbType.Int).Value = ordstr.ToString();
        cmd.Parameters.Add("@loginname", SqlDbType.VarChar, 512).Value = Page.User.Identity.Name;
        if(currentDate != null)
        { 
            // only set the parameter if it's not null, this will allow the SQL sproc to use its existing logic        
            cmd.Parameters.Add("@datecompleted", SqlDbType.DateTime).Value = currentDate;
        }

        try
        {
            conn.Open();
            cmd.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            //TODO: save log for now;
            int ex_errorid = 0;
            string ex_msg = string.Concat((ex != null && ex.Message != null) ? ex.Message.ToString() : (ex != null && ex.InnerException != null) ? ex.InnerException.ToString() : "No Message Found ", (ex != null && ex.StackTrace != null) ? ex.StackTrace.ToString() : "No Strack Trace ");
            int ex_genericid = 0;
            string ex_username = (Page != null && Page.User != null && Page.User.Identity != null && Page.User.Identity.Name != null) ? Page.User.Identity.Name : "No user found";
            Jobs.log_somewhere ex_errorlog = new Jobs.log_somewhere();
            ex_errorlog.log_secos_error(ex_errorid, ex_msg, ex_genericid, ex_username);
        }
    }
}