【问题标题】:SQL clone record with a unique index具有唯一索引的 SQL 克隆记录
【发布时间】:2012-03-23 04:37:49
【问题描述】:

是否有一种干净的方法可以在 SQL 中克隆具有索引的记录(自动增量)。我想克隆除索引之外的所有字段。我目前必须枚举每个字段,并在插入选择中使用它,我宁愿不明确列出所有字段,因为它们可能会随着时间而改变。

【问题讨论】:

    标签: sql mysql database


    【解决方案1】:

    除非您想学习动态 SQL,否则不会。既然你写了“干净”,我假设不是。

    编辑:既然他要求提供动态 SQL 示例,我就试一试。目前我没有连接到任何数据库,所以这不是我的想法,几乎肯定需要修改。但希望它能抓住事物的精神:

    -- Get list of columns in table
    SELECT INTO #t
    EXEC sp_columns @table_name = N'TargetTable'
    
    -- Create a comma-delimited string excluding the identity column
    DECLARE @cols varchar(MAX)
    SELECT @cols = COALESCE(@cols+',' ,'') + COLUMN_NAME FROM #t WHERE COLUMN_NAME <> 'id'
    
    -- Construct dynamic SQL statement
    DECLARE @sql varchar(MAX)
    SET @sql = 'INSERT INTO TargetTable (' + @cols + ') ' +
        'SELECT ' + @cols + ' FROM TargetTable WHERE SomeCondition'
    
    PRINT @sql -- for debugging
    EXEC(@sql)
    

    【讨论】:

    • 你有使用动态sql的例子吗?
    • 这是 MySQL 特有的吗?带有来自 EXEC stmt 的数据的 SELECT INTO 语法在 SQL Server AFAIK 上不起作用。
    • 不,它本来是 SQL Server。不记得这是否有效。如果没有,您可以显式创建临时表,然后使用 INSERT INTO #t EXEC sp_columns...
    【解决方案2】:

    我无法想到简单而干净的方法,但是从您问题中的一些项目来看,我会担心您的底层架构。也许你有一个绝对正当的理由想要这样做,但通常你想尽量避免数据库中的重复,而不是让它们更容易导致。此外,明确命名列通常是一个好主意。如果您要链接到外部代码,它可以确保您在添加新列时不会破坏该链接。如果您不是(听起来您可能不在这种情况下),我仍然更喜欢列出列,因为它迫使我查看更改/新列的效果 - 即使只是为了查看代码并确定添加新列没有问题。

    【讨论】:

    • 我们的客户将复制一个项目。项目的所有属性都是一样的,只是它是表中的一个新条目(新索引),它会有不同的外键引用。
    • 听起来您正在寻找的内容应该在 UI 中完成。作为项目的正常编辑屏幕的一部分,让他们使用现有项目的信息预填充字段。到那时,这只是一个正常的保存。如果添加新列,则无论如何都需要更改该屏幕。
    【解决方案3】:
    DROP TABLE #tmp_MyTable
    
    SELECT * INTO #tmp_MyTable
    FROM MyTable
    WHERE MyIndentID = 165
    
    ALTER TABLE #tmp_MyTable
    DROP Column MyIndentID
    
    INSERT INTO MyTable
    SELECT * 
    FROM #tmp_MyTable
    

    【讨论】:

      【解决方案4】:

      这也处理唯一键项目编号以及主键。

      CREATE TEMPORARY TABLE projecttemp SELECT * FROM project WHERE projectid='6';
      ALTER TABLE projecttemp DROP COLUMN projectid;
      UPDATE projecttemp SET projectnum = CONCAT(projectnum, ' CLONED');
      INSERT INTO project SELECT NULL,projecttemp.* FROM projecttemp;
      

      【讨论】:

        【解决方案5】:

        您可以创建一个插入触发器来执行此操作,但是,您将无法使用显式 ID 进行插入。相反,它将始终使用序列中的值。

        【讨论】:

          【解决方案6】:

          您可以创建一个触发器来为您执行此操作。为确保触发器仅适用于克隆,您可以创建一个单独的用户名 CLONE 并使用它登录。或者,更好的是,如果您的 DBMS 支持它,创建一个名为 CLONE 的角色,任何用户都可以使用该角色登录并进行克隆。触发代码类似于:

          if (CURRENT_ROLE = 'CLONE') then
             new.ID = assign new id from generator/sequence
          

          当然,您只会将该角色授予允许克隆记录的用户。

          【讨论】:

            猜你喜欢
            • 2013-11-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-11
            • 1970-01-01
            • 2012-04-12
            • 1970-01-01
            相关资源
            最近更新 更多