【问题标题】:How do I correctly use wildcards in a prepared statement?如何在准备好的语句中正确使用通配符?
【发布时间】:2016-09-28 07:55:56
【问题描述】:

我的使用通配符的 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();

【问题讨论】:

  • id.Value = string.Format("{0}%", cid);
  • Hello SQL 注入
  • @BrendanGreen 在准备好的声明中?
  • @TonyDong 这并没有解决问题,我仍然得到零记录。我认为这不起作用,因为 sql 必须在值周围加上单引号。 sql 最终需要看起来像:SELECT GRAD_COMMENCEMENT_DATE FROM GRADUATES WHERE GRADUATES_ID LIKE '0123456%'
  • Tony Dong 是对的,该值必须是不带引号的字符串。尝试使用= 而不是LIKE,看看你会得到什么。一次解决问题,而不是一次解决多个步骤。

标签: c# sql-server prepared-statement


【解决方案1】:

改变之后

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

并删除

query.Prepare();

它将为您返回所有结果。 我在本地测试过,我不知道你为什么需要在这里准备?

【讨论】:

  • 我们可以把这归咎于我没有完全理解.Prepare() 的目的。但是,我进行了这些更改,但仍然没有看到任何记录返回。我将在 OP 中更新我的代码。
  • @dusk 我们能否再次检查您的数据库实际上是否具有这些值?可以直接运行查询DECLARE @cid VARCHAR(7)SET @cid = 'something%'SELECT GRAD_COMMENCEMENT_DATE FROM GRADUATES WHERE GRADUATES_ID LIKE @cid,查看结果吗?
  • 好吧。我认为这偶然发现了这里的问题。 cid 是 7 位 varchar,但通配符使它成为 8。所以即使基本查询有效,但当我执行 declare & set 语句时它失败了。当我将 7 更改为 8 时,它起作用了。感谢@Rob 和 Tony 的所有帮助!!!
【解决方案2】:

有点基本,但它有效:

使用预设变量,填充它们,然后将它们传递给 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)
}

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

【讨论】:

  • 使用.AddWithValue() 的问题似乎是.Prepare() 要求参数具有明确设置的类型。
  • 没有太多 SQL 经验,但您需要使用.Prepare()吗?
  • 老实说我不知道​​。我一直在其他地方使用它来构建准备好的语句,并且在这里只遇到了通配符的问题。我用通配符查看的示例似乎没有使用.Prepare(),但它们也没有使用.ExecuteReader()。当我最初开始学习如何使用 System.Data 库时,我看到的所有内容都是使用 .Prepare()
  • @dusk 我相信使用它是一种很好的做法,因为它可以作为一种“故障保险”(如果您的陈述有问题,它会抛出异常)。但如果你知道你的陈述是正确的,那么你不应该使用它。
【解决方案3】:

为什么不这样呢?

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) + '%'";

【讨论】:

    猜你喜欢
    • 2012-01-05
    • 2014-09-04
    • 1970-01-01
    • 2020-01-04
    • 1970-01-01
    相关资源
    最近更新 更多