0

所以我不知道这是否可能,甚至是否可取,但我试图弄清楚如何在我的网络服务中创建一个可由用户动态构建的更新命令。基本上,目标是有一个包含 x 个列的表,并且用户应该能够更新任意数量的列,而不必为未更新的列传递 null 或现有值。例如,一个人可能想跑步

UPDATE calendar_table
SET title = 'Some new Title'
WHERE (id = 12344)

而另一个用户可能想要执行此操作

UPDATE calendar_table
SET title = 'New Event', type = 'Meeting', note = 'Meet with new client'
WHERE (id = 12344)

所以下面是我试图使用的,但我不断收到一个异常,指出“WHERE”附近有一个问题,这让我相信这与我试图处理更新字符串的方式有关

String MyConnStr = ConfigurationManager.ConnectionStrings["MainConnStr"].ConnectionString;
        SqlConnection connection = new SqlConnection(MyConnStr);
        SqlCommand Query = new SqlCommand("UPDATE dbo.calendar_table " +
            "SET @newText " +
            "WHERE (id = @appointmentID)", connection);
        Query.Parameters.Add("@newText", SqlDbType.VarChar).Value = note;
        Query.Parameters.Add("@appointmentID", SqlDbType.VarChar).Value = appointment;
        Query.CommandType = CommandType.Text;
        try
        {
            connection.Open();
            Query.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
        finally
        {
            connection.Close();
            Query.Dispose();
        }

任何帮助或想法将不胜感激,因为我能想到的唯一其他选择就是创建具有所有可能值的 Web 服务,然后将未更改的现有值与值一起传递。

4

1 回答 1

0

您的代码将假定知道将为给定更新设置哪些字段。因此,您可以将每个字段动态添加到SET子句和Parameters集合中。为每个字段使用参数还可以避免注释中提到的 SQL 注入问题。

根据您的示例代码的语法,我假设它是 C#。以下是您可以处理更新变量、用户定义的字段数的一种方法。

假设存在包含用户输入值的变量: userInputTitleuserInputTypeuserInputNote等。

id字段包含在SET子句中以消除是否在SET子句中每个动态添加的字段之前添加逗号的问题。这样做的副作用是,即使用户没有定义任何字段,也可以运行更新。

顺便说一句,使用using而不是显式地尝试清理实现IDisposable接口的对象被认为是更好的做法,因此下面的示例被相应地重写。using 语句将关闭连接并处理连接和命令。此外, usingParameters.AddWithValue()避免了指定参数的数据类型的需要。

我没有测试过这段代码。

String MyConnStr =
        ConfigurationManager.ConnectionStrings["MainConnStr"].ConnectionString;
using (SqlConnection connection = new SqlConnection(MyConnStr))
{
    using (SqlCommand Query = new SqlCommand())
    {
        try
        {
            Query.Connection = connection;
            String sql = "UPDATE dbo.calendar_table SET id = @appointmentID";
            // The has-field-been-updated-by-user logic below assumes the
            // fields are strings.  Different logic might be necessary
            // for other data types.
            if (!String.IsNullOrWhitespace(userInputTitle))
            {
                sql += ", title = @title";
                Query.Parameters.AddWithValue("@title", userInputTitle);
            }
            if (!String.IsNullOrWhitespace(userInputType))
            {
                sql += ", type = @type";
                Query.Parameters.AddWithValue("@type", userInputType);
            }
            if (!String.IsNullOrWhitespace(userInputNote))
            {
                sql += ", note = @note";
                Query.Parameters.AddWithValue("@note", userInputNote);
            }
            // Additional fields...
            sql += " WHERE (id = @appointmentID)";
            Query.Parameters.AddWithValue("@appointmentID", appointmentID);
            Query.CommandText = sql;
            Query.CommandType = CommandType.Text;
            connection.Open();
            Query.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
    }
}
于 2013-02-22T05:19:36.787 回答