【问题标题】:How to pass a Variable/Function into SQL Query?如何将变量/函数传递给 SQL 查询?
【发布时间】:2020-02-03 17:22:01
【问题描述】:

我试图在表上插入一行,但我似乎无法将 TASK_ID 作为值/变量/函数传递到 SQL 语句中。在整个应用程序中,为了获取 TASK_ID,我使用:

Dim taskID = ds.Tables("ReminderTable").Rows(Count).Field(Of Integer)("TASK_ID")

一些有用的上下文代码:

da.Fill(ds, "ReminderTable")

Count = ds.Tables("ReminderTable").Rows.Count - 1

这是我想要做的:

da.InsertCommand = New OleDbCommand("INSERT INTO ACTIVITY (TASK_ID, ACTIVITY_CDE, ACTIVITY_NOTE) VALUES (3827, 1, 'Reminder Sent: ' & Now)", Connection)

我不断收到错误消息

没有为一个或多个必需参数指定值。

当我将 3827 替换为变量/函数/引用时。

该语句按原样工作,但我需要将上述语句中的“3827”替换为 TASK_ID,但它不会接受我的变量、函数或我使用的位置在整个项目的其他地方引用相同的东西。

我在 Visual Studio 2019 中工作,使用 Microsoft Access 数据库

【问题讨论】:

  • 请编辑问题并发布在尝试连接变量时失败的语法。
  • 将日期嵌入文本条目是混合数据。其自己的日期/时间字段中的日期值将是更有用的信息。 Activity_CDE 应说明该活动是“已发送提醒”。
  • da.InsertCommand.Parameters.AddWithValue("@taskID", taskID) 参数化查询,一切似乎都在工作。我会考虑到这一点@June7

标签: sql database vb.net ms-access


【解决方案1】:

使用String Interpolation

da.InsertCommand = New OleDbCommand(
$"INSERT INTO ACTIVITY (TASK_ID, ACTIVITY_CDE, ACTIVITY_NOTE) 
  VALUES ({taskID}, 1, 'Reminder Sent: ' & Now())", Connection)

如果从 .NET 获取日期和时间,您也可以使用字符串插值来添加它

da.InsertCommand = New OleDbCommand(
$"INSERT INTO ACTIVITY (TASK_ID, ACTIVITY_CDE, ACTIVITY_NOTE) 
  VALUES ({taskID}, 1, 'Reminder Sent: {DateTime.Now}')", Connection)

【讨论】:

  • 在连接的日期/时间值之后的右撇号分隔符在哪里?
  • @June7 不需要一个,因为 Now() Function 是由 Access 调用的,而不是 .NET。
  • 但是 Access 不会期望文本值使用撇号分隔符吗?编译后的字符串如:INSERT …, 'Reminder Sent: 2/3/2020 2:00:00 PM')
  • @June7 不。这个插入命令完全可以被 Access 接受:INSERT INTO ACTIVITY (TASK_ID, ACTIVITY_CDE, ACTIVITY_NOTE) VALUES (3827, 1, 'Reminder Sent: ' & Now())
  • 好吧,我会很危险的!我已经使用嵌入在 SQL 字符串中的 Now() 或 Date() 函数来保存到日期/时间字段,但我猜我从来不需要将日期/时间与我建议 OP 也不要这样做的文本连接起来。
【解决方案2】:

尝试将实际维度添加到您的第一行代码中,如下所示:

Dim taskID as Integer = ds.Tables("ReminderTable").Rows(Count).Field(Of Integer)("TASK_ID")

你也可以这样写:

将 taskID 调暗为 Integer = ds.Tables("ReminderTable").Rows(Count)("TASK_ID")

希望对你有帮助

【讨论】:

  • 我试过了,但没有用。感谢您的帮助,但似乎参数化是这里的方法。 da.InsertCommand.Parameters.AddWithValue("@taskID", taskID)
【解决方案3】:

这是一个非常基本的示例。它在 C# 中,但您可以轻松地将其转换为 VB。重要的部分是cmd.Parameters.AddWithValue

public int Create(EmployeeClassification classification)
{
    if (classification == null)
        throw new ArgumentNullException(nameof(classification), $"{nameof(classification)} is null.");

    const string sql = @"INSERT INTO EmployeeClassification (EmployeeClassificationName) VALUES(@EmployeeClassificationName )";

    using (var con = OpenConnection())
    using (var cmd = new OleDbCommand(sql, con))
    {
        cmd.Parameters.AddWithValue("@EmployeeClassificationName", classification.EmployeeClassificationName);
        return cmd.ExecuteNonQuery();
    }
}

来源:https://grauenwolf.github.io/DotNet-ORM-Cookbook/SingleModelCrud.htm#ado.net

【讨论】:

  • 如果使用parameters,最好定义数据类型和长度,依赖隐式转换。请不要宣传使用AddWithValue...
  • AddWithValue 有什么问题?这就是我用来解决问题的方法:P
  • AddWithValue 在搜索时可能会导致性能下降,因为它默认为nVarChar,而您的列可能是varChar。不匹配会干扰索引。但如果这是一个问题,您总是可以覆盖 SQL 数据类型。
猜你喜欢
  • 1970-01-01
  • 2019-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多