C# 如何在准备好的语句中正确使用通配符?

C# 如何在准备好的语句中正确使用通配符?,c#,sql-server,prepared-statement,C#,Sql Server,Prepared Statement,我使用通配符编写的SQL语句返回的记录为零。我发现的所有示例都没有使用.Prepare()方法,该方法要求SqlParameter具有指定的类型。因此,当我将参数设置切换到使用.AddWithValue(“@cid”,cid+“%”)时,Prepare()会引发一个关于没有显式设置类型的异常 ctx.Open(); string sql = "SELECT GRAD_COMMENCEMENT_DATE FROM GRADUATES WHERE GRADUATES_ID LIKE @cid"; S

我使用通配符编写的SQL语句返回的记录为零。我发现的所有示例都没有使用.Prepare()方法,该方法要求SqlParameter具有指定的类型。因此,当我将参数设置切换到使用
.AddWithValue(“@cid”,cid+“%”)时,
Prepare()会引发一个关于没有显式设置类型的异常

ctx.Open();
string sql = "SELECT GRAD_COMMENCEMENT_DATE FROM GRADUATES WHERE GRADUATES_ID LIKE @cid";
SqlCommand query = new SqlCommand(sql,ctx);
SqlParameter id = new SqlParameter("@cid", SqlDbType.VarChar, 7);
id.Value = string.Format("{0}%", cid);
query.Parameters.Add(id);
//query.Prepare();
SqlDataReader rs = query.ExecuteReader();

string grad_date = "";
while (rs.Read())
{
  //no records =(
  grad_date = rs["GRAD_COMMENCEMENT_DATE"].ToString();
  Console.WriteLine("grad date: "+grad_date);
}
rs.Close();
ctx.Close();

位基本,但它可以工作:

使用预设变量,填充它们,然后将它们传递到SQL查询函数中

string id = //value

void SQL Query(id)
{
    string idFilter = null;
    if (id != null)
        idFilter = "WHERE GRADUATES_ID LIKE @cid"
    else
        idFilter = String.Empty;

    conn.Open();

    string sql = "SELECT GRAD_COMMENCEMENT_DATE FROM GRADUATES " + idFilter;
    cmd = new SqlCommand(sql, ctx);

    if (id != null)
        cmd.Parameters.AddWithValue("@cid", id)
}

(为可怕的结构/糟糕的语法道歉)

位基本,但它可以工作:

使用预设变量,填充它们,然后将它们传递到SQL查询函数中

string id = //value

void SQL Query(id)
{
    string idFilter = null;
    if (id != null)
        idFilter = "WHERE GRADUATES_ID LIKE @cid"
    else
        idFilter = String.Empty;

    conn.Open();

    string sql = "SELECT GRAD_COMMENCEMENT_DATE FROM GRADUATES " + idFilter;
    cmd = new SqlCommand(sql, ctx);

    if (id != null)
        cmd.Parameters.AddWithValue("@cid", id)
}
(为可怕的结构/糟糕的语法道歉)

为什么不这样

string sql = "SELECT GRAD_COMMENCEMENT_DATE FROM GRADUATES WHERE GRADUATES_ID LIKE @cid + '%'";
或者如果
@cid
不总是varchar

string sql = @"SELECT GRAD_COMMENCEMENT_DATE 
FROM GRADUATES WHERE GRADUATES_ID LIKE CONVERT(VARCHAR,@cid) + '%'";
为什么不这样呢

string sql = "SELECT GRAD_COMMENCEMENT_DATE FROM GRADUATES WHERE GRADUATES_ID LIKE @cid + '%'";
或者如果
@cid
不总是varchar

string sql = @"SELECT GRAD_COMMENCEMENT_DATE 
FROM GRADUATES WHERE GRADUATES_ID LIKE CONVERT(VARCHAR,@cid) + '%'";
在你改变之后

id.Value = string.Format("{0}%", cid);
并删除

query.Prepare();
它将为您返回所有结果。 我在本地进行了测试,我不知道您为什么需要在这里进行准备?

在您更改后

id.Value = string.Format("{0}%", cid);
并删除

query.Prepare();
它将为您返回所有结果。

我在本地计算机上进行了测试,不知道为什么需要在这里准备?

id.Value=string.Format(“{0}%”,cid);你好,SQLInjection@BrendanGreen在一份事先准备好的声明中?@TonyDong这并不能解决问题,我仍然没有收到任何记录。我认为这不起作用,因为sql必须在值周围加单引号。sql需要以如下方式结束:
选择毕业生的毕业日期,毕业生ID如“0123456%”
Tony Dong是对的,该值必须是一个不带引号的字符串。尝试使用
=
而不是像
那样的
,看看你得到了什么。一次解决一个步骤,而不是一次解决多个步骤。id.Value=string.Format(“{0}%”,cid);你好,SQLInjection@BrendanGreen在一份事先准备好的声明中?@TonyDong这并不能解决问题,我仍然没有收到任何记录。我认为这不起作用,因为sql必须在值周围加单引号。sql需要以如下方式结束:
选择毕业生的毕业日期,毕业生ID如“0123456%”
Tony Dong是对的,该值必须是一个不带引号的字符串。尝试使用
=
而不是像
那样的
,看看你得到了什么。一次一步解决问题,而不是一次解决多个步骤。使用
.AddWithValue()
的问题似乎是
.Prepare()
要求参数具有显式设置的类型。SQL方面的经验不多,但您是否需要使用
.Prepare()
?老实说,我不知道。我一直在其他地方使用它来构建准备好的语句,在这里只遇到了通配符的问题。我看到的通配符示例似乎没有使用
.Prepare()
,但它们也没有使用
.ExecuteReader()
。当我开始学习如何使用System.Data库时,我所看到的一切都是使用
.Prepare()
@dash,我相信使用它是一种很好的做法,因为它可以作为一种“故障保护”(如果您的语句有问题,它将抛出异常)。但是,如果您知道您的语句是正确的,那么就不需要使用它。使用
.AddWithValue()
的问题似乎是
.Prepare()
要求参数具有显式设置的类型。对SQL没有太多经验,但您是否需要使用
.Prepare()
?老实说,我不知道。我一直在其他地方使用它来构建准备好的语句,在这里只遇到了通配符的问题。我看到的通配符示例似乎没有使用
.Prepare()
,但它们也没有使用
.ExecuteReader()
。当我开始学习如何使用System.Data库时,我所看到的一切都是使用
.Prepare()
@dash,我相信使用它是一种很好的做法,因为它可以作为一种“故障保护”(如果您的语句有问题,它将抛出异常)。但是如果你知道你的陈述是正确的,那么你就不需要使用它。我们可以把这归咎于我没有完全理解
.Prepare()
的目的。但是,我做了这些更改,仍然没有看到任何返回的记录。我会在OP中更新我的代码。@Dask我们能再检查一下你的数据库是否真的有这些值吗?你能运行这个查询吗
DECLARE@cid VARCHAR(7)
SET@cid='something%'
直接从毕业生那里选择毕业日期,然后检查结果吗。我想这是偶然发现了这个问题。cid是一个7位数的varchar,但通配符将其设置为8。因此,即使基本查询可以工作,当我执行declare&set语句时,它还是失败了。当我把7号换成8号时,它工作了。谢谢@Rob和Tony的帮助!!!我们可以把这归咎于我没有完全理解
.Prepare()
的目的。但是,我做了这些更改,仍然没有看到任何返回的记录。我会在OP中更新我的代码。@Dask我们能再检查一下你的数据库是否真的有这些值吗?你能运行这个查询吗
DECLARE@cid VARCHAR(7)
SET@cid='something%'
直接从毕业生那里选择毕业日期,然后检查结果吗。我想这是偶然发现了这个问题。cid是一个7位数的varchar,但通配符将其设置为8。因此,即使基本查询可以工作,当我执行declare&set语句时,它还是失败了。当我把7号换成8号时,它工作了。谢谢@Rob和Tony的帮助!!!