将多行更新到SQL表中

假设有一个完全填充的数据数组String [n] [3] myData。

我想做这个:

for (String[] row : myData) { SQL = "update mytable set col3 = row[2] where col1 = row[0] and col2=row[1];" } 

显然我已经离开了很多,但我想尽可能简洁地表达这个想法。

有一种简单的方法可以在单个DB命令中执行此操作吗? 一个不那么简单的方法怎么样?

编辑:数据不是来自另一个表(这是一个网络表单提交 – 多选择考试)
看到应用程序是面向Web的,它必须是注塑certificate。 参数化查询是我的首选方式。
我正在使用MS-SQL Server 2005

编辑:关闭并重新询问多个数据库更新:

编辑:重新打开,因为这似乎是一个受欢迎的问题

如果您使用的是Sql Server,则可以使用SqlBulkCopy。 您首先必须将数据放在DataTable中,这很简单,因为您已经将它放在字符串数组中。

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx

这取决于您使用的数据库。 如果您使用的是SQL Server 2008,则可以使用存储过程TABLE参数 。 这允许您将所有值传递到单个表中的存储过程中,然后您可以执行以下操作:

 update mytable set mytable.col1 = @tbl.col1 from mytable inner join @tbl on mytable.col2 = @tbl.col2 

如果您使用的是SQL Server 2005,则可以使用XML。 将值格式化为XML,然后使用XQuery语句(即“nodes”和“value”)来解析XML。 这也可以在单个SQL语句中完成,并且不需要存储过程。

你可以创建一个大字符串:

 for (String[] row : myData) { SQL += "update mytable set col3 = row[2] where col1 = row[0] and col2=row[1];" } sqlDriver.doInsertQuery(SQL); // change this to your way of inserting into the db 

并立即全部承诺。 我对SQL不太熟悉,所以我会怎么做。

sql引擎只是将它拆分为’;’ 并自己单独插入。 可以将它全部添加到字符串中。 这与将多个更新/插入的大字符串复制到sql提示符中的方式相同

这可能不是您想要的答案,但是从数据库的角度来看,打开事务,执行语句然后提交事务将会执行您所描述的操作。

在事务完成之前,数据库的其他用户的数据库状态不会发生变化,这可能是首选的效果。

如果您在数据访问层中使用Enterprise Library ,则可以在.Net中创建事务,遍历过程调用,然后从.Net提交/回滚所有事务。

 DbTransaction transaction = connection.BeginTransaction(); try { for (String[] row : myData) { ListDictionary params = new Specialized.ListDictionary(); params.add("@col3", row[2]); params.add("@col1", row[0]); params.add("@col2", row[1]); executeNonQuery("myUpdateProcedure", params); } transaction.commit(); } catch(Exception ex) { transaction.rollback(); throw ex; } finally { connection.close(); } 

如果由于某种原因您无法使用上面建议的方法之一执行更新,下面的低效率方法可能对您有用。

 SQL = "Update myTable Set Col3 = Case " for (String[] row : myData) { SQL += "When Col1 = " + Row[0] + " and Col2 = " + Row[1] + " then " + row[2] + " " } SQL + = "Else Col3 end" 

看起来你想要更新A,在具有B和C代码的行上。(A,B,C)在myData中存储为元组(行)。 不是吗?

也许(如果你使用的是Microsoft SQL Server ……我不知道它是否存在于Oracle中,可能是)你可以使用带有UPDATE的JOIN。 您可以在与另一个表连接的表上声明更新。 如果myData来自另一个表,那么你可以做(​​这不是正确的语法):

 UPDATE whatchanges wc INNER JOIN changes c ON  SET wc.col1 = c.newvalue WHERE .... 

(如果要在“更改”表中应用所有更改,则不必使用WHERE,INNER JOIN已经选择了正确的行)。

当然,这种更新存在局限性。 它是MS SQL专有的。 所以,如果是你的情况,我建议在MS网站上寻找它(关键字:UPDATE和JOIN)

并不是的。 您可以使用相同的循环创建字符串,然后将您的值作为参数传递,但这仍然是多个数据库命令。

 for each whatever sql += "UPDATE ... ;" end for execute (sql) 

我怀疑你需要使用多个SQL语句。 你可能会找到一个处理细节的包装器,但在下面我想象它会为每个UPDATE迭代运行一个SQL语句。

发出违反值表的更新:

 UPDATE myTable SET col3=c FROM myTable JOIN ( SELECT 1 as a, 2 as b, 'value1' as c UNION ALL SELECT 3 as a, 4 as b, 'value2' as c -- etc... ) x ON myTable.col1=xa AND myTable.col2=xb 

所以你就这样把它放在一起:

 // make one of these for each row String.Format("SELECT {0} as a, {1} as b, '{2}' as c", row[0], row[1], row[2].Replace("'","''")) // put it together string expr = "UPDATE myTable SET col3=c FROM myTable JOIN (" + String.Join(stringformatarray, " UNION ALL ") + ") x ON myTable.col1=xa AND myTable.col2=xb" 

或者您可以使用StringBuilder将它们组合在一起。

然后,当然,你执行这一个字符串。