【问题标题】:Stored Procedure works but not when called with ExecuteNonQuery存储过程有效,但在使用 ExecuteNonQuery 调用时无效
【发布时间】:2020-06-10 04:23:55
【问题描述】:

我有以下函数来更新数据库中的一些数据:

public Boolean ModificarDireccion(DireccionBE dirBE) {
    con.ConnectionString = conection.GetCon();
    cmd.Connection = con;
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.CommandText = "PERSONA.ActualizarDireccion";

    try {
        cmd.Parameters.Clear();
        cmd.Parameters.AddWithValue("@id_direccion", dirBE.Id_direccion);
        cmd.Parameters.AddWithValue("@tipo_direccion", dirBE.Tipo_direccion);
        cmd.Parameters.AddWithValue("@id_persona", dirBE.Id_persona);
        cmd.Parameters.AddWithValue("@dir_pais", dirBE.Dir_pais);

        cmd.Parameters.AddWithValue("@dir_provincia", dirBE.Dir_provincia);
        cmd.Parameters.AddWithValue("@dir_ciudad", dirBE.Dir_ciudad);
        cmd.Parameters.AddWithValue("@dir_distrito", dirBE.Dir_distrito);
        cmd.Parameters.AddWithValue("@dir_linea_1", dirBE.Dir_linea_1);

        cmd.Parameters.AddWithValue("@dir_linea_2", dirBE.Dir_linea_2);
        cmd.Parameters.AddWithValue("@dir_codigo_postal", dirBE.Dir_codigo_postal);

        con.Open();
        cmd.ExecuteNonQuery();

        success = true;
    } catch (SqlException x) {
        success = false;
        throw new Exception(x.Message);
    } finally {
        if (con.State == ConnectionState.Open) {
            con.Close();
        }
        cmd.Parameters.Clear();
    }
    return success;
}

使用以下存储过程:

ALTER PROCEDURE [PERSONA].[ActualizarDireccion]
    (
        @id_direccion [int],
        @tipo_direccion [tinyint],
        @id_persona [int],
        @dir_pais [tinyint],
        @dir_provincia [int],
        @dir_ciudad [int],
        @dir_distrito [int],
        @dir_linea_1 [nvarchar](100),
        @dir_linea_2 [nvarchar](100),
        @dir_codigo_postal [varchar](10)
    )
AS
    SET NOCOUNT ON
    SET XACT_ABORT ON

    BEGIN TRANSACTION
        UPDATE PERSONA.DIRECCION
        SET  tipo_direccion = @tipo_direccion, id_persona = @id_persona, dir_pais = @dir_pais, dir_provincia = @dir_provincia, dir_ciudad = @dir_ciudad, dir_distrito = @dir_distrito, dir_linea_1 = @dir_linea_1, dir_linea_2 = @dir_linea_2, dir_codigo_postal = @dir_codigo_postal
        WHERE (id_direccion = @id_direccion)
    COMMIT

这是表的结构:

CREATE TABLE [PERSONA].[TELEFONO](
    [id_telefono] [int] IDENTITY(1,1) NOT NULL,
    [tipo_telefono] [tinyint] NOT NULL,
    [id_persona] [int] NOT NULL,
    [codigo_pais] [varchar](5) NOT NULL,
    [campo_1] [varchar](5) NOT NULL,
    [campo_2] [varchar](5) NOT NULL,
    [campo_3] [varchar](5) NOT NULL,
    [ext] [varchar](5) NULL,
 CONSTRAINT [PK__TELEFONO_bf60e690] PRIMARY KEY CLUSTERED 
(
    [id_telefono] ASC,
    [tipo_telefono] ASC,
    [id_persona] ASC
)
) ON [PRIMARY]
GO

当我调用此函数时,它不会更新数据库。但是,如果我在 SSMS 中手动使用它,我可以成功更新数据。我错过了什么?

我尝试调试,一步一步进行,对象“dirBE”中有正确的数据,但是更改并没有放入数据库中。没有错误,什么都没有。

【问题讨论】:

  • 你得到什么异常? SQL Server 应该有一些响应。您能否调试并检查卡在哪里。
  • 调试你的代码并在codecmd.ExecuteNonQuery();之前观察cmd code并查看参数
  • @CaiusJard 我仍然认为这是一般的最佳实践,即使在这种情况下风险较小。了解一个人的参数数据类型并正确编码很重要。
  • 您发布了另一个创建表。
  • 顺便说一句,由于各种原因,您的 catch 块很差:如果您正在抛出,您不需要设置返回值,您不应该捕获异常并在您抛出新的可以只使用 throw 关键字来重新抛出原始并保留其所有堆栈跟踪,您根本不应该抛出一个通用的。这个 catch 块对你没有任何作用,应该被删除到 try/finally 或者整个 try 被取消以支持 using

标签: c# sql-server


【解决方案1】:

试一试。如果它有效,则说明您的代码有问题,Visual Studio 将为您生成一个您可以复制(或仅使用)的有效代码

现在您可以右键单击在表格适配器中进行的查询并选择预览,以使用 VS 测试运行它等

要在您自己的代码中使用它,请执行以下操作:

new YourQueriesTableAdapterName().YourChosenMethodName(
  dirBE.id_direccion, 
  ...
);

ide 肯定会生成工作代码(如果您想将其复制出来,您可以在 YourDataSet.Designer.cs 中找到它,或者您可以将其保留在那里并只使用 tableadapter - 它本质上与您相同'重新处理您的代码,创建一个调用存储过程的单独类)所以如果这遇到与您相同的问题,那么我会说它归结为以下几件事之一:

  • 您正在查看与您的程序正在更新的数据库不同的数据库
  • 您为 id_direction 传递的值在表中不存在
  • 存在一些值转换错误或预期不匹配,这意味着您认为 c# 发送的值与它实际发送的值不同(请参阅上述错误)

呃..就是这样!

【讨论】:

    【解决方案2】:
    using (SqlConnection con = new SqlConnection(conection.GetCon()))
    {
        using (SqlCommand cmd = new SqlCommand("PERSONA.ActualizarDireccion", con))
        {
            cmd.CommandType = CommandType.StoredProcedure;
    
            cmd.Parameters.Add("@id_direccion", SqlDbType.Int).Value = dirBE.Id_direccion;
            cmd.Parameters.Add("@tipo_direccion", SqlDbType.TinyInt).Value = dirBE.Tipo_direccion;
            cmd.Parameters.Add("@id_persona", SqlDbType.Int).Value = dirBE.Id_persona;
            cmd.Parameters.Add("@dir_pais", SqlDbType.TinyInt).Value = dirBE.Dir_pais;
            cmd.Parameters.Add("@dir_provincia", SqlDbType.Int).Value = dirBE.Dir_provincia;
            cmd.Parameters.Add("@dir_ciudad", SqlDbType.Int).Value = dirBE.Dir_ciudad;
            cmd.Parameters.Add("@dir_distrito", SqlDbType.Int).Value = dirBE.Dir_distrito;
            cmd.Parameters.Add("@dir_linea_1", SqlDbType.NVarChar).Value = dirBE.Dir_linea_1;
            cmd.Parameters.Add("@dir_linea_2", SqlDbType.NVarChar).Value = dirBE.Dir_linea_2;
            cmd.Parameters.Add("@dir_codigo_postal", SqlDbType.VarChar).Value = dirBE.Dir_codigo_postal;
    
            con.Open();
            cmd.ExecuteNonQuery();
        }
    }
    

    【讨论】:

    • 不幸的是,它仍然不适用于这种方法。谢谢
    • @dominique120 你收到错误还是没有插入。另外请为您的表格发布 CreateTable 代码,我会看看是否可以复制。
    • 我已经添加了表格结构。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    • 2018-10-13
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多