无法使用我的存储过程

时间:2009-08-31 03:12:08

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

我有以下方法,应该是我的应用程序的通用“保存到SQL”方法。

protected void EjecutarGuardar(string ProcedimientoAlmacenado, object[] Parametros)
        {
            SqlConnection Connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);

            SqlCommand Command = Connection.CreateCommand();             
            Command.CommandType = CommandType.StoredProcedure;
            foreach (object X in Parametros)
            {
                Command.Parameters.Add(X);
            }            

            Connection.Open();
            Command.ExecuteNonQuery();
            Connection.Close();

            Connection.Dispose();
        }

我必须传递StoredProcedure的NAME和一个填充参数的数组。我有点迷失在这一点上。我应该在哪里使用存储过程“ProcedimientoAlmacenado”的名称?

我想也许是Command.Command ????? some someign?但我迷失在那里。有什么帮助吗?

编辑:为了简单起见,我想说我的数据库中有一个名为“ABC”的存储过程。我怎么能将它与我的代码中的SqlCommand“Command”相关联?

4 个答案:

答案 0 :(得分:3)

Command.CommandText = ProcedimientoAlmacenado

参数也必须有名称。 Parametros数组是否包含SqlParameter对象或通用C#对象?

如果参数是通用C#对象,最好传入名称和值的字典:

protected void EjecutarGuardar(string ProcedimientoAlmacenado, 
    Dictionary<string, object> Parametros)
{
    using (SqlConnection Connection = new SqlConnection(...))
    {
        Connection.Open();
        SqlCommand Command = Connection.CreateCommand()
        Command.CommandText = ProcedimientoAlmacenado;
        Command.Connection = Connection;       
        Command.CommandType = CommandType.StoredProcedure;
        foreach (string name in Parametros.Keys)
        {
          Command.Parameters.AddWithValue(name, Parametros[name] ?? DBNull.Value);
        }            
        Command.ExecuteNonQuery();
    }
}

这是一种快速而肮脏的方法。请注意,此方法通常存在问题,因为AddWithValue将为字符串传递NVARCHAR类型的参数,而不是VARCHAR,并且使用ad-hoc SQL会导致VARCHAR列上的索引SARG能力问题(因为转换将始终从VARCHAR到NVARCHAR,反之亦然。但是,存储过程并不是一个问题,因为过程具有类型参数,因此如果使用参数类型VARCHAR创建过程,则会对VARCHAR进行强制强制。

你也会遇到传递NULL参数的问题,所以你需要做的事情,参数必须是DBNull.Value而不是null

Command.Parameters.AddWithValue(name, Parametros[name] ?? DBNull.Value);

在高性能系统上,此方法还会不必要地污染执行缓存,因为AddWithValue将传递NVARCHAR(<exact length of the string>)类型的参数,而不是NVARCHAR(<length of the database type>)。因此Paramaters.AddWithValue("@name", "John")Parameters.AddwithValue("@name", "Doe")将在缓存中创建两个不同的计划,因为一个使用NVARCHAR(4)类型的参数调用,另一个使用参数NVARCHAR(3)调用,并且SQL可以看到它们将缓存计划为不同类型。这对简单项目来说不是问题,但是对于更复杂和高性能的项目,建议明确设置参数类型。

我的建议是避免使用这种通用的“一刀切”程序,而是使用正确的类型参数为每个数据库过程编写带有显式C#包装器的数据访问层。强类型数据集实际上可以做到这一点,另一个替代方案(我最喜欢的和我经常使用的)是使用创建C#包装器的XSLT样式表从XML文件生成整个数据访问slayer。当然,源XML是从数据库元数据本身中提取的。

答案 1 :(得分:0)

Command.ComandText = "storedProcName";

答案 2 :(得分:0)

Command.CommandText = "ProcedimientoAlmacenado"; Command.CommandType = CommandType.StoredProcedure;之前或之后这不是强制性的,但这就是我的方式。

答案 3 :(得分:0)

将SqlCommand对象的CommandText属性设置为存储过程的名称:

Command.CommandText = "MyStoredProcedureName";
相关问题