[英]Update multiple rows into SQL table
假设有一个完全填充的数据字符串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的,它必须是注入证明。 参数化查询是我的首选方式。
我正在使用MS-SQL Server 2005
编辑:关闭并重新询问多个数据库更新:
编辑:重新打开,因为这似乎是一个受欢迎的问题
这取决于您使用的数据库。 如果您使用的是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语句中完成,并且不需要存储过程。
如果您使用的是Sql Server,则可以使用SqlBulkCopy。 您首先必须将数据放在DataTable中,这很简单,因为您已经将它放在字符串数组中。
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx
你可以做一个大字符串:
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提示符中的方式相同
这可能不是您想要的答案,但是从数据库的角度来看,打开事务,执行语句然后提交事务将会执行您所描述的操作。
在事务完成之前,数据库的其他用户的数据库状态不会发生变化,这可能是首选的效果。
看起来你想要更新A,在具有B和C代码的行上。(A,B,C)在myData中存储为元组(行)。 不是吗?
也许(如果你使用的是Microsoft SQL Server ......我不知道它是否存在于Oracle中,可能是)你可以使用带有UPDATE的JOIN。 您可以在与另一个表连接的表上声明更新。 如果myData来自另一个表,那么你可以做(这不是正确的语法):
UPDATE whatchanges wc INNER JOIN changes c ON <yourcondition>
SET wc.col1 = c.newvalue
WHERE ....
(如果要在“更改”表中应用所有更改,您当然不必使用WHERE,INNER JOIN已经选择了正确的行)。
当然,这种更新存在局限性。 它是MS SQL专有的。 所以,如果是你的情况,我建议在MS网站上寻找它(关键字:UPDATE和JOIN)
如果您在数据访问层中使用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"
并不是的。 您可以使用相同的循环创建字符串,然后将值作为参数传递,但这仍然是多个数据库命令。
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=x.a AND myTable.col2=x.b
所以你就这样把它放在一起:
// 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=x.a AND myTable.col2=x.b"
或者您可以使用StringBuilder将它们组合在一起。
然后,当然,你执行这一个字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.