繁体   English   中英

将多行更新到SQL表中

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM