【问题标题】:How to pass parameters in proper manner in C#?如何在 C# 中以正确的方式传递参数?
【发布时间】:2013-05-16 17:49:01
【问题描述】:

我的存储过程如下:

ALTER PROCEDURE [dbo].[Insert_tblCustomer] 
-- Add the parameters for the stored procedure here
@Username varchar(20) = null, 
@Password varchar(20)= null,
@UserType varchar(20)='User',
@FirstName varchar(50)=null,
@LastName varchar(50)=null,
@DateOfBirth varchar(50)=null,
@Gender varchar(10)=null,
@Unit_No int = null,
@St_No int=null,
@St_Name varchar(20)=null,
@Suburb varchar(20)=null,
@State varchar(20)=null,
@Postcode int=null,
@Email varchar(50)='',
@Phone varchar(15)=null

作为... 并且有 5 个字段,即用户名、密码、名字、姓氏和电子邮件是必须字段。 现在从 c# 开始,我正在尝试这个:

dbConnection target = new dbConnection(); // TODO: Initialize to an appropriate value
string _query = string.Empty; // TODO: Initialize to an appropriate value

SqlParameter[] param = new SqlParameter[5]; // TODO: Initialize to an appropriate value
param[0] = new SqlParameter("@Username", "hakoo");
param[1] = new SqlParameter("@Password", "hakoo");
param[2] = new SqlParameter("@FirstName", "Hakoo");
param[3] = new SqlParameter("@LastName", "Hakoo");
param[4] = new SqlParameter("@Email", "haks@abc.com");
bool expected = true; // TODO: Initialize to an appropriate value
bool actual;
actual = target.Execute_InsertQuery("dbo.Insert_tblCustomer", param);

但是,我得到了 Assertfail 异常。我是新手使用存储过程进行测试。 谁能纠正我哪里错了?

“添加断言部分”

bool expected = true; // TODO: Initialize to an appropriate value
bool actual;
actual = target.Execute_InsertQuery("dbo.Insert_tblCustomer", param);

dbConnection 是我创建的核心类,我在其中放置通用查询:

public bool Execute_InsertQuery(string _query, SqlParameter[] param) 
{

    try
    {
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = OpenConnection();
        cmd.CommandText = _query;

        cmd.Parameters.AddRange(param);
        cmd.ExecuteNonQuery();
        return true;
    }
    catch (Exception ex)
    {
        Console.Write(ex.StackTrace.ToString());
        return false;
    }
}

获取错误的更新: 我尝试以这种方式传递所有参数:

dbConnection c = new dbConnection();
System.Data.SqlClient.SqlParameter[] param = new System.Data.SqlClient.SqlParameter[15];
param[0] = new SqlParameter("@Username", "hakoo");

param[1] = new SqlParameter("@Password", "hakoo");
param[2] = new SqlParameter("@UserType", "User");
param[3] = new SqlParameter("@FirstName", "Hakoo");
param[4] = new SqlParameter("@LastName", "Hakoo");
param[5] = new SqlParameter("@DateOfBirth", "02/11/88");
param[6] = new SqlParameter("@Gender", "");
param[7] = new SqlParameter("@Unit_No", null);
param[8] = new SqlParameter("@St_No", 25);
param[9] = new SqlParameter("@St_Name", "anc st");
param[10] = new SqlParameter("@Suburb", "ancst");
param[11] = new SqlParameter("@State", "assadd@few");
param[12] = new SqlParameter("@Postcode", 2615);
param[13] = new SqlParameter("@Email", "abc@def.com.au");
param[14] = new SqlParameter("@Phone", "165103548");
c.Execute_InsertQuery("dbo.Insert_tblCustomer", param);

但是为此,我收到了这个错误:

参数化查询 '(@Username nvarchar(5),@Password nvarchar(5),@UserType nvarchar(' 需要参数 '@Unit_No',但未提供该参数。我可以在 SQL Server 中执行此存储过程。

【问题讨论】:

  • 目标的类型是什么?
  • 断言失败的细节是什么?
  • 它们都是 varchar。刚刚得到 AssertFailException。我希望插入时为 True,但实际值为 False。
  • 什么是“target.Execute_InsertQuery”?看起来这里有有趣的代码
  • 另外,一般来说“必须”字段不应该指定默认值

标签: c# sql-server


【解决方案1】:

没有单一的最佳方式来传递参数。我说的是,让 SqlParameter 之类的东西远离命令 (SqlCommand) 是个坏主意 - 如果您不处理数据库但我会将它们传递为字符串/整数/等,或作为对象的成员。

至于这种情况下出了什么问题:没有看到与命令相关的代码,我只能说:42

【讨论】:

  • 我注意到了你的建议,我从 MUST 字段中删除了 null,我想在这里做的是,说我有这样的 SP 参数 (p1,p2,p3,p4,p5) 所以通过使用 SqlParameter[] p ,我只分配 p[0] = (p1,"p1"), p[1] = (p2,"p2") 和 p[2]=(p4,"p4")。我的困惑是 p 的索引是否引用了参数? like : 0 指 p1, 1 指 p2, 2 指 p3.... 等等?
  • @Hakoo 取决于提供者。 SqlClient 按名称传递参数。一些提供者通过索引传递。无论哪种方式,让调用者给你 SqlParameter[] 都很难看。我强烈建议你看看“dapper”的优雅以及它是如何传递参数的。实际上,您可以使用 dapper 轻松调用存储过程。
  • 嗨,Marc,我很难理解你。你能举一些例子吗?我只使用存储过程并传递参数。
  • @Hakoo 我将通过代码进行解释。如果那是我,我的整个代码将是(通过“dapper”):conn.Execute("dbo.Insert_tblCustomer", new { Username = "hakoo", ... , Email = "haks@abc.com" }, commandType: CommandType.StoredProcedure); - 没有别的。
【解决方案2】:

指定命令类型可能会有所帮助。

   SqlCommand cmd = new SqlCommand();
   cmd.Connection = OpenConnection();
   cmd.CommandText = _query;
   cmd.CommandType = CommandType.StoredProcedure;

【讨论】:

  • 很高兴为您提供帮助。奇怪的是,它只是将存储过程命令视为文本查询,这是默认设置。创建 sql 命令时,最好指定命令类型。
  • 我最初是这样做的,但后来我认为我可以处理查询(将参数放入查询)以及具有相同功能的存储过程,所以我删除了它。
猜你喜欢
  • 2018-07-10
  • 1970-01-01
  • 2013-03-14
  • 1970-01-01
  • 1970-01-01
  • 2022-12-03
  • 1970-01-01
相关资源
最近更新 更多