1

我要在具有大量列的表上进行一系列插入,例如:

INSERT INTO Table1 (A,B,C,...,Z) VALUES (@a,@b,@c,...,@z)

所有字段(A 到 Z)都可以为空。如果未能显式设置已写入命令文本的命令参数,则无法执行插入。

由于列名不是真正连续的(都有相当随机的名称),是否有一种简单的方法可以循环遍历命令文本中的参数并将它们设置为DBNull.Value?还是我必须手动写出:

cmd.Parameters.AddWithValue("@a", DBNull.Value);
cmd.Parameters.AddWithValue("@b", DBNull.Value);
cmd.Parameters.AddWithValue("@c", DBNull.Value);
...
cmd.Parameters.AddWithValue("@z", DBNull.Value);

或者是构建实际使用的列并将它们连接在一起(和使用的参数),然后设置使用的参数的正确解决方案?

我倾向于回避查询的串联解决方案,以避免潜在的注入攻击。

4

4 回答 4

4

这是将每个参数设置为 null 的更简洁/更简洁的方法:

foreach (var param in new[] { "@a", "@b", ... })
    cmd.Parameters.AddWithValue(param, DBNull.Value);

我也倾向于回避连接解决方​​案,但是如果您的列具有在数据库中定义的默认值,那么这可能会有所不同,如果您在insert语句中明确将它们设置为 null,则这些默认值会(?)被覆盖。

于 2012-06-26T13:00:19.857 回答
2

是的,您可能会编写代码来读取列名并将它们设置为默认值 NULL,其缺点是读取系统数据库需要更高的权限。

我强烈建议您考虑编写一个存储过程,例如,

CREATE PROCEDURE [dbo].[spInsertTable1]
    @a type = NULL,
    @b type = NULL,
    @c type = NULL,
    -- ...
    @z type = NULL
AS
BEGIN
    INSERT INTO Table1 (A, B, C, ...., Z) VALUES
    (@a, @b, @c, ..., @z)
END

你可以他们这样称呼它,

command.CommandText = "dbo.spInsertTable1";
command.CommandType = CommandType.StoredProcedure;
command.Paramaters.AddWithValue("@a", somevalue);
// No more are needed the stored procedure will default them to NULL.
于 2012-06-26T13:02:24.263 回答
1

您需要先对表执行某些操作以获取表定义,然后您可以遍历该定义并构建您的参数。

因此,您可以执行“从 tableName 中选择前 0 *”,将其检索到数据读取器中,然后像这样遍历字段:

 for(int i=0;i<reader.FieldCount;i++)
 {
    cmd.Parameters.AddWithValue("@" + reader.GetName(i), DBNull.Value);
 }

假设每个字段都以相同的方式表示为参数。

于 2012-06-26T13:03:50.987 回答
1

一种解决方案是创建一个存储不同参数名称的数组,如果您没有设置它们的值,则对其进行迭代以将它们中的每一个设置为 DBNull,如下所示:

// Assume paramNames is an array of strings containing each paramter name
foreach(strign param in paramNames)
{
    // Note: 'SettingValue()' and 'value' are a placeholders, as I don't 
    // know how you're determining which parameters are being used.
    if( SettingValue(param) )
    {
        cmd.Parameters.AddWithValue(param, value);
    }
    else
    {
        cmd.Parameters.AddWithValue(param, DBNull.Value);
    }
}

我同意回避串联解决方案。要问自己的一件事是:如果您的插入中有这么多未使用的(和可为空的)参数,为什么首先要有它们?您应该能够在不包括它们的情况下执行 INSERT。

如果您需要它们以供将来参考,您可以在数据库中创建一个存储过程,而不是使用参数化查询,并为可为空的参数提供默认值。然后,您只需指定正在使用的参数。

于 2012-06-26T13:04:21.700 回答