Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 带可选参数的Sql更新命令?_C#_Sql - Fatal编程技术网

C# 带可选参数的Sql更新命令?

C# 带可选参数的Sql更新命令?,c#,sql,C#,Sql,我将大约500000个对象插入到数据库中,其中许多对象是相同的(在数据库中具有相同的主键表示),但其他字段可能不同,所以我使用的方法是“更新-如果没有受影响的行-插入”。问题是,有时一个对象的某个字段设置为null(无法从文件读取),并且已经在数据库中设置了某个值,因此我将其更新为null=擦除它。)如何实现只更新非null字段的场景 下面是一个简单的例子,说明我现在是如何做到这一点的: private const string UpdateKun = "UPDATE pde.Kun SET J

我将大约500000个对象插入到数据库中,其中许多对象是相同的(在数据库中具有相同的主键表示),但其他字段可能不同,所以我使用的方法是“更新-如果没有受影响的行-插入”。问题是,有时一个对象的某个字段设置为null(无法从文件读取),并且已经在数据库中设置了某个值,因此我将其更新为null=擦除它。)如何实现只更新非null字段的场景

下面是一个简单的例子,说明我现在是如何做到这一点的:

private const string UpdateKun = "UPDATE pde.Kun SET Jmeno=@Jmeno WHERE Licence=@Licence";
private const string InsertKun = "INSERT INTO pde.Kun ([Licence], [Jmeno], [VykonnostniStupen]) VALUES (@Licence, @Jmeno, @VykonnostniStupen)";

var cmd = new SqlCommand(UpdateKun, conn, tran);
cmd.Parameters.AddWithValue("@Licence", kun.Licence);
cmd.Parameters.AddWithValue("@Jmeno", kun.Jmeno);
RepairNulls(cmd.Parameters);
if (cmd.ExecuteNonQuery() > 0) return;

cmd = new SqlCommand(InsertKun, conn, tran);
cmd.Parameters.AddWithValue("@Licence", kun.Licence);
cmd.Parameters.AddWithValue("@Jmeno", kun.Jmeno);
cmd.Parameters.AddWithValue("@VykonnostniStupen", 0);
RepairNulls(cmd.Parameters);
cmd.ExecuteNonQuery();


private void RepairNulls(SqlParameterCollection col)
    {
        foreach (SqlParameter param in col.Cast<SqlParameter>().Where(param =>  param.Value == null))
        {
            param.Value = DBNull.Value;
        }
    }
private const string UpdateKun=“UPDATE pde.Kun SET Jmeno=@Jmeno其中license=@license”;
private const string InsertKun=“插入pde.Kun([license]、[Jmeno]、[VykonnostniStupen])值(@license、@Jmeno、@VykonnostniStupen)”;
var cmd=新的SqlCommand(UpdateKun、conn、tran);
cmd.Parameters.AddWithValue(“@license”,kun.license);
cmd.Parameters.AddWithValue(“@Jmeno”,kun.Jmeno);
RepairNulls(命令参数);
if(cmd.ExecuteNonQuery()>0)返回;
cmd=新的SqlCommand(InsertKun、conn、tran);
cmd.Parameters.AddWithValue(“@license”,kun.license);
cmd.Parameters.AddWithValue(“@Jmeno”,kun.Jmeno);
cmd.Parameters.AddWithValue(“@VykonnostniStupen”,0);
RepairNulls(命令参数);
cmd.ExecuteNonQuery();
私有void RepairNulls(SqlParameterCollection列)
{
foreach(col.Cast()中的SqlParameter param,其中(param=>param.Value==null))
{
param.Value=DBNull.Value;
}
}
将更新更改为:

UPDATE pde.Kun 
SET Jmeno=@Jmeno 
WHERE Licence=@Licence
  AND @Jmeno IS NOT NULL
如果要更新多个列,请执行以下操作:

UPDATE pde.Kun 
SET Jmeno = COALESCE(@Jmeno, Jmeno)
  , ColumnB = COALESCE(@ColumnB, ColumnB) 
WHERE Licence=@Licence

不要仅仅为了检查行是否存在而更新数据库

SELECT COUNT(*) FROM pde.Kun WHERE Licence=@Licence

只需检查返回值是否大于0

一些SQL产品的功能与您用一条语句描述的一样:
INSERT。。。如果重复更新…
@ypercube,因为它是一个
SqlCommand
它的SQL Server。然后它将是合并,只要它是2005年或更大是的,我不是真的喜欢sql,但我会假设它应该有这样的功能:)我使用sql server 2008,express edition,我会查找合并语法,感谢Scheck也回答:好主意,似乎是解决方案,即使我有点害怕性能,因为这只是一个对象的例子,通常我插入的对象有20个字段,在数据库中除了主键外,所有字段都可以为空。我认为使用
COALESCE()
函数不会有性能问题。不过,使用500K更新和500K插入插入500K行可能是错误的。根据您的DBMS(SQL Server?什么版本?),您可能会有更好的选择来逐个插入/更新行。在需要插入行的情况下,如果行已经存在,则更新行,使用我的方法可以保存一个SQL调用(尝试更新,如果它不影响任何行,请插入它,这最多是2次调用,通常只有1次,因为在我的情况下,重复性很高,并且更新成功),如果我要使用select count查找它是否存在,我将不得不执行所有方式的2个调用,查找它是否存在,然后更新或插入,但您没有使用相同的数据更新行。select语句的性能要好得多,因为它使用表的索引来查找该行是否存在。应该会有所帮助