【问题标题】:Is there a standard way to duplicate a row in a database table?有没有一种标准的方法来复制数据库表中的一行?
【发布时间】:2010-11-08 09:18:44
【问题描述】:

我想复制一行,当然不是键,没有明确使用字段名称。
是否有 SQL 方式,或者我必须通过代码枚举字段名称?

我不想明确使用字段名称,因为我想最小化代码和数据库依赖关系。

我将在 Ms Access 2003 中使用它。如果不存在标准方法,我会提到它。

【问题讨论】:

    标签: sql ms-access duplicate-data


    【解决方案1】:
    INSERT INTO `<table>` (column1, column2, ...) -- Not IDENTITY columns
    SELECT column1, column2, ... FROM ...
    

    这还允许您为主键列等插入替换值。我已经使用它和一个公共表表达式,从 2 月份获取一组测试数据,并假装它们'真的是从六月开始的。

    我知道你说过你想在没有字段名称的情况下这样做,但我认为你不能。这也不是一个好主意,因为它会将您与列的顺序联系起来。

    【讨论】:

    • John,我想避免这种代码。也许我会用 VBA 代码自动生成它。
    • @Nick D. 你必须这样做。没有通用的说法:插入所有列,除了我不想要的。
    【解决方案2】:

    如果您无需担心任何独特性:

    INSERT INTO <table> (SELECT * FROM <table> WHERE <condition>)
    

    否则,John Saunders' answer 可能是你最好的选择。

    【讨论】:

    • 他要求重复行但没有提及任何字段名称;解决唯一约束可防止您获得完全相同的副本,并要求您提及要复制的每个字段名称。
    • 那么,@Noah 的正确答案肯定是“不,你做不到”。
    • 它不起作用。 Access 用 INSERT INTO 语法错误提醒我。是的,我确实使用了主键,但我不知道主键是否是导致该错误的原因。
    • @Nick:您将 和 替换为适当的表格和条件,对吧?此外,主键被视为唯一键,并且会阻止我的答案起作用。
    • 在“插入前”添加一个触发器并自动增加您的 PK,您就已经建立了有史以来最好的气体工厂。否则你可以按照约翰的建议去做!
    【解决方案3】:

    如果您的主键字段具有自动标识符,那么您很可能能够编写脚本来询问系统以查找不在 PK 中的字段,并将现有值用于那些不在 PK 中的字段并且只插入那些(或为 PK 字段插入 null)。

    因此,我认为不会有“标准”方式。

    【讨论】:

      【解决方案4】:

      我不是 Access 人员,但在 SQL Server 中,您可以在 SQL Server Management Studio 中选择“脚本表为 --> 插入”。您可以轻松地修改它以将您想要的行过滤到 INSERT INTO SELECT 语句中。

      Access 中可能存在类似的东西?

      【讨论】:

      • 我也不是 Access 人 :) 好的,我去看看。
      • Access 中不存在此类工具。或者 Jet/ACE,就此而言。
      • 太遗憾了,我想您可以将表导入 SQL Server,然后创建脚本并在 Access 中运行它,但这可能比它值得付出更多的努力,并假设用户拥有 SQL Server .
      【解决方案5】:

      就像人们在我之前所说的那样,您可以执行“INSERT INTO TBL SELECT * FROM TBL WHERE X=Y”,您将得到一行。如果您有主键,这将失败。

      如果你没有PK,那么你可能有更大的问题。

      这是一个链接表吗?如果是这样,则没有数据库依赖关系,因为您正在处理 ODBC 链接。在这种情况下,您可以轻松地使用它来获取表格的列列表:

      SELECT TOP 0 * FROM TBL(在链接的 tbl 上需要往返服务器)
      您得到一个空白记录集,然后您只需遍历列。

      【讨论】:

      • 1,1s/主键/唯一约束/ - 主键只是一种唯一约束。
      【解决方案6】:

      Ms Access 2003 面向解决方案

      我有一个表单,用户可以在其中按下按钮来创建当前记录的新版本。
      Ms Access 中的那部分很简单:

      DoCmd.GoToRecord , , acNewRec
      

      现在我需要使用来自其他记录的数据更新表单上的所有字段(控件与表字段绑定),除了键,即“id”字段。

      我想出了以下例程,这对我很有用:

      Private Sub UpdateRow(tblname As String, key_name As String, key_value As String)
          Dim Rst As Recordset
          Dim field As field
      
          Set DB = CurrentDb
          Set Rst = DB.OpenRecordset("select * from " & tblname & " where " & _
            key_name & "=" & key_value, dbOpenDynaset)
      
          For Each field In Rst.Fields
             If field.Name <> key_name Then
                 Form(field.Name) = field
             End If
          Next field
      
          Rst.Close
          Set Rst = Nothing
          Set DB = Nothing
      End Sub
      


      我是这样使用它的:

      DoCmd.GoToRecord , , acNewRec
      UpdateRow "TableName", "KeyName", "some_previous_key_value"
      Form.Refresh
      

      【讨论】:

        【解决方案7】:

        当您提供替换值时,您需要明确地提供键的字段名称,因此根本不可能采用“标准”方式。

        ...除非您的所有表都有一个键,并且都具有相同的名称(ID 很流行),并且每个键都包含一个具有 IDENTITY(自动编号)属性的列,在这种情况下,您实际上会根本没有键,只是一种使用 IDENTITY 值来唯一标识重复行的方法!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-21
          • 2020-10-18
          • 2013-06-01
          • 1970-01-01
          • 2020-08-28
          • 2023-03-07
          • 2011-07-21
          相关资源
          最近更新 更多