C# 多列插入中的默认命令参数
我在一个包含大量列的表上进行了一系列插入,例如:C# 多列插入中的默认命令参数,c#,sql,sql-server,.net-3.5,C#,Sql,Sql Server,.net 3.5,我在一个包含大量列的表上进行了一系列插入,例如: INSERT INTO Table1 (A,B,C,...,Z) VALUES (@a,@b,@c,...,@z) 所有字段(A到Z)都可以为空。如果未能显式设置在命令文本中写入的命令参数,则无法执行插入 由于列名不是真正连续的(所有列名都是非常随机的),是否有一种简单的方法可以循环使用命令文本中的参数并将其设置为DBNull.Value?或者我必须手动写出: cmd.Parameters.AddWithValue("@a", DBNull.V
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);
或者,正确的解决方案是构建实际使用的列并将它们连接在一起(以及使用的参数),然后设置使用的参数
我倾向于回避查询的连接解决方案,以避免潜在的注入攻击。这里有一种更简洁/更清晰的方法将每个参数设置为null:
foreach (var param in new[] { "@a", "@b", ... })
cmd.Parameters.AddWithValue(param, DBNull.Value);
我也倾向于回避连接解决方案,但如果您的列在DB中定义了默认值,这可能会有所不同,如果您在
insert
语句中显式地将它们设置为null,则会覆盖默认值。这里有一种更简洁/更清晰的方法将每个参数设置为null:
foreach (var param in new[] { "@a", "@b", ... })
cmd.Parameters.AddWithValue(param, DBNull.Value);
我也倾向于回避连接解决方案,但如果您的列在DB中定义了默认值,这可能会有所不同,即(?)如果在
insert
语句中显式将列名设置为null,则会被覆盖。是的,您可能会编写代码来读取列名并将其设置为默认值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.
是的,您可能可以编写读取列名的代码,并将它们设置为默认值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.
您需要首先对表执行一些操作来获取表定义,然后可以迭代该定义并构建参数 因此,您可以执行“从tableName中选择top 0*”,将其检索到datareader中,然后循环遍历如下字段:
for(int i=0;i<reader.FieldCount;i++)
{
cmd.Parameters.AddWithValue("@" + reader.GetName(i), DBNull.Value);
}
for(int i=0;i您需要对表执行一些操作,以首先获取表定义,然后可以迭代该定义并构建参数
因此,您可以执行“从tableName中选择top 0*”,将其检索到datareader中,然后循环遍历如下字段:
for(int i=0;i<reader.FieldCount;i++)
{
cmd.Parameters.AddWithValue("@" + reader.GetName(i), DBNull.Value);
}
for(int i=0;i一种解决方案是创建一个存储不同参数名的数组,如果不设置它们的值,则迭代该数组以将它们中的每一个设置为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);
}
}
我同意回避串联解决方案。有一件事要问你自己:如果你的插入中有这么多未使用(且可为空)的参数,为什么你首先要使用它们?你应该能够执行插入,而不必从一开始就包含它们
如果需要这些参数供将来参考,可以在数据库中创建存储过程,而不是使用参数化查询,并为可为空的参数提供默认值。然后只需指定正在使用的参数。一种解决方案是创建一个存储不同参数名称的数组,在t如果不设置它们的值,则将它们分别设置为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);
}
}
我同意回避串联解决方案。有一件事要问你自己:如果你的插入中有这么多未使用(且可为空)的参数,为什么你首先要使用它们?你应该能够执行插入,而不必从一开始就包含它们
如果您需要它们作为将来的参考,您可以在数据库中创建一个存储过程,而不是使用参数化查询,并为可为null的参数提供默认值。然后您只需指定正在使用的参数。我想,如果我只需要设置@a,其余的设置为null,我会继续设置@a。然后执行与您的答案类似的循环,如果命令上的参数列表不包含该参数,则仅添加一个检查以仅将该参数添加为null。我想说,如果我只需要设置@a,其余的设置为null:我将继续设置@a。然后执行与您的答案类似的循环,仅添加一个检查以仅添加参数如果命令上的参数列表中尚未包含该参数,则参数为null。