SQL:对INSERT和UPDATE使用相同的字符串?

时间:2009-04-26 04:50:18

标签: sql insert sql-update

我一直在使用的INSERT语法是

INSERT INTO TableName VALUES (...)

我一直在使用的UPDATE语法是

UPDATE TableName SET ColumnName=Value WHERE ...

所以在我的所有代码中,我必须生成2个字符串,这将产生类似这样的

insertStr = "(27, 'John Brown', 102)";
updateStr = "ID=27, Name='John Brown', ItemID=102";

然后单独使用它们

"UPDATE TableName SET " + updateStr + " WHERE ID=27 " +
"IF @@ROWCOUNT=0 "+
"INSERT INTO TableName VALUES (" + insertStr + ")"

当我使用30列的表格时,它开始困扰我。

我们不能只在INSERT和UPDATE生成一个字符串吗?

例如。在UPDATE语句上使用insertStr或在INSERT语句上使用updateStr,还是以一种全新的方式?

7 个答案:

答案 0 :(得分:7)

我认为你需要一种全新的方法。您可以 SQL Injection 开放。为我们提供一些示例代码,说明如何获取数据输入并将语句发送到数据库。 alt text http://goose.ycp.edu/~weddins/440/S09%20IFS440%20Bobby%20Drop%20Tables.PNG

答案 1 :(得分:6)

据我所知,你所描述的内容在ANSI SQL中是不可能的,或者我所知道的任何扩展。但是,我对MySQL很熟悉,它可能完全取决于你正在使用的RDBMS。例如,MySQL具有“INSERT ... ON DUPLICATE KEY UPDATE ...”语法,类似于您在那里发布的语法,并将INSERT查询与UPDATE查询组合在一起。好处是你将两个可能的操作组合成一个查询,但是,查询的INSERT和UPDATE部分肯定是不同的。

通常,这种事情可以通过应用程序中的ORM层抽象出来。就原始SQL而言,我会对你所描述的任何语法感兴趣。

答案 2 :(得分:2)

那么,没有陈述怎么样?你可能想要查看一个ORM来为你处理这个......

答案 3 :(得分:2)

有些DBMS'有一个扩展来执行此操作,但为什么不提供一个功能来为您执行此操作?我们之前实际上已经这样做了。

我不确定你使用的语言是什么,但它可能有关联数组,你可以写下这样的语言:

pk{"ID"}   = "27"
val{"Name"} = "'John Brown'"
val{"ItemID"} = "102"
upsert ("MyTable", pk, val)

并且,如果它没有关联数组,您可以使用多个基于整数的字符串数组来模拟它们。

在我们的upsert()函数中,我们只构造了一个字符串(update,然后insert如果update失败)并将其传递给我们的DBMS。我们将主键与其他字段分开,因为这使得更新语句的构造变得更加容易(主键列在where子句中,其他列只是设置了)。

上面调用的结果将导致以下SQL(我们对失败的update进行了不同的检查,但我已将@@rowcount放入此示例中):

update MyTable set
    Name = 'John Brown',
    ItemID = 102
    where ID = 27
if @@rowcount=0
    insert into MyTable (ID, Name, ItemID) values (
        27,
        'John Brown',
        102
    )

这是一个对我们有用的解决方案。毫无疑问还有其他人。

答案 4 :(得分:1)

某些数据库具有完全相同的专有扩展。

我同意INSERT和UPDATE的语法可以更加一致,但这只是生活中的一个事实 - 它现在不会改变。对于许多场景,最好的选择是你的“全新方式”:使用对象关系映射库(甚至像.NET DataSet这样的弱茶层)来抽象差异,并停止担心低级SQL句法。当然,这不是每个应用程序都可行的选项,但它允许您只构造或更新对象,调用Save方法并让库为您找出SQL语法。

答案 5 :(得分:1)

如果你考虑一下,INSERT和UPDATE是完全一样的。它们将字段名称映射到值,但UPDATE具有过滤器。 通过创建关联数组,其中键是字段名称,值是您要分配给字段的值,您可以使用映射。您只需要根据INSERT或UPDATE将其转换为正确的字符串格式。 您只需创建一个函数,该函数将根据给定的参数处理转换。

答案 6 :(得分:1)

SQL Server 2008:

MERGE dbo.MyTable AS T
USING
 (SELECT  
  @mykey AS MyKey
  @myval AS MyVal
  ) AS S

ON (T.MyKey = S.MyKey)

WHEN MATCHED THEN 
  UPDATE  SET 
    T.MyVal = S.MyVal
WHEN NOT MATCHED THEN
  INSERT (MyKey, MyVal)
  VALUES (S.MyKey, S.MyVal)

MySQL的:

INSERT (MyKey, MyVal)
INTO MyTable
VALUES({$myKey}, {$myVal})
ON DUPLICATE KEY UPDATE myVal = {$myVal}