【问题标题】:SQL Server Auto increment key primary key while mering new values into tableSQL Server 自动递增键主键,同时将新值合并到表中
【发布时间】:2014-01-25 16:17:00
【问题描述】:

我正在编辑一个 SQL 服务器存储过程,目前它使用游标和 @@Identity 来执行以下操作。我正在尝试转向更基于集合的方法。

根据我收集到的信息,我正在尝试将临时表(新信息)合并到当前表(旧信息)中,没有特定的顺序,我需要执行以下操作。 - 创建新行 - 创建新的 PrimaryKeys - 将旧信息(PrimaryKey 除外)复制到新行中。 - 将两个旧列更改为“新”信息。

我“认为”我遇到的问题是如何为所有这些行创建新的 primaryKey 值。 -> 如何获取数据库中“最高”的旧主键值?

所以;这是看起来有点假的 SQL 代码。

Merge Target as T
Using @TemporaryTable as S --Source
on T.vPrimaryID = S.vPrimaryID
AND T.Arbitary = S.Arbitrary --Arbitrary business rule, shouldn't matter
WHEN MATCHED THEN
UPDATE SET
PrimaryKey = newPrimaryKey -- This is where I'm having problems 
Col2 = S.col2
Col3 = T.col3
Col4 = T.col4
Col5 = GetDate() --new Timestamp

数据库设置了“版本控制”,primaryKey 是“版本”,因此它应该是主要的、唯一的且不为空。

为了在运行后完全公开,我需要 TARGET 表来更新其先前匹配的行并将布尔标志从 true 设置为 false。 (基本上是软删除) 那部分我现在不太担心。

您知道primaryKey 将如何工作吗?我觉得我在概念上遗漏了一些东西。 我正在使用 MS-SQL 服务器。由于工作中的 IP 政策,我无法提供旧的 proc 或真实代码。

【问题讨论】:

  • PrimaryKey 真的是主键吗,即您无法更改的东西?您可以使用 OUTPUT 子句从行中获取任何数据(注意复数。),例如Id 值。 OUTPUT 可以与INSERTUPDATEDELETEMERGE 一起使用,并在UPDATE 的情况下提供对前后值的访问。一个非常值得放在口袋里的工具。并避免@@IDENTITY。
  • 得到输出后;我将如何增加?我觉得我可以做类似以下的事情。 SELECT TOP 1 PrimaryKey FROM Source ORDER BY PrimaryKey DESC
  • 您可能是对的,我不知道 PrimaryKey... 是否是 PrimaryKey 以及是否存在实际约束;但由于我们的版本控制策略,我需要保持旧行不变并将其加一。如何检查它是否真的是 MS SQL 中的主键?
  • 我不确定您是否正确使用了短语 Primary Key。
  • @Zane 我对它很松懈。主键不是用于查找其余信息的非空、不同/唯一值吗?

标签: sql sql-server


【解决方案1】:

自从上一个创建存储过程并在过程中使用@@IDENTITY 函数的人以来,我将它作为一个 IDENTITY 列(自动增量),插入新行时不需要为它提供任何值,它会生成下一个可用的价值。

您在问题中显示的代码根本不是fake SQL Code,它是正确的合法MERGE STATEMENT,当您想在一个SQL语句中执行多个操作时使用(DELETE,UPDATE,INSERT)。

没有关于此演示示例中使用的表变量的所有信息。既然您已经提到要向数据添加新行。

您可以简单地在合并语句中添加另一个条件来添加目标表中不存在的行。并且它已经在更新已经存在的行。

你可以这样做......

Merge Target as T
Using(SELECT * FROM @TemporaryTable) as S   --Source
on T.vPrimaryID = S.vPrimaryID
AND T.Arbitary = S.Arbitrary --Arbitrary business rule, shouldn't matter
WHEN MATCHED THEN
UPDATE SET
                      -- For Primary key its an Identity column it will 
T.Col2 = S.col2         -- generate the new values for you 
T.Col3 = S.col3
T.Col4 = S.col4
T.Col5 = GetDate() 

WHEN NOT MATCHED THEN 
 INSERT (T.Col2,T.Col3,T.Col4,T.Col5,....)  -- Do not use the Identity column here 
  VALUES (S.Col2,S.Col3,S.Col4,S.Col5,....)  -- it will be auto generated for you

【讨论】:

  • 由于项目被隐藏(需要复杂的业务规则/规格表),我无法在工作中实现此功能;但您确实为我解决了问题,感谢您的帮助。
  • 没问题,至少下次当您看到MERGE STATEMENT 时,您会知道它是合法的 sql 代码而不是假 sql :)
  • 我自己做了那个sql;我只是将其作为伪代码的概念练习。我知道这是“真实的”,很惊讶它完全合法。我的工作经常使用游标,而合并语句非常非常少。
  • CURSORS 哎哟....尽量避免使用游标。我认为几乎没有必须使用游标的情况,否则临时表、CTE 和排名函数几乎可以在不使用游标的情况下实现一切。
猜你喜欢
  • 2012-06-15
  • 1970-01-01
  • 2011-06-19
  • 2021-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多