【发布时间】:2012-03-23 04:37:49
【问题描述】:
是否有一种干净的方法可以在 SQL 中克隆具有索引的记录(自动增量)。我想克隆除索引之外的所有字段。我目前必须枚举每个字段,并在插入选择中使用它,我宁愿不明确列出所有字段,因为它们可能会随着时间而改变。
【问题讨论】:
是否有一种干净的方法可以在 SQL 中克隆具有索引的记录(自动增量)。我想克隆除索引之外的所有字段。我目前必须枚举每个字段,并在插入选择中使用它,我宁愿不明确列出所有字段,因为它们可能会随着时间而改变。
【问题讨论】:
除非您想学习动态 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)
【讨论】:
我无法想到简单而干净的方法,但是从您问题中的一些项目来看,我会担心您的底层架构。也许你有一个绝对正当的理由想要这样做,但通常你想尽量避免数据库中的重复,而不是让它们更容易导致。此外,明确命名列通常是一个好主意。如果您要链接到外部代码,它可以确保您在添加新列时不会破坏该链接。如果您不是(听起来您可能不在这种情况下),我仍然更喜欢列出列,因为它迫使我查看更改/新列的效果 - 即使只是为了查看代码并确定添加新列没有问题。
【讨论】:
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
【讨论】:
这也处理唯一键项目编号以及主键。
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;
【讨论】:
您可以创建一个插入触发器来执行此操作,但是,您将无法使用显式 ID 进行插入。相反,它将始终使用序列中的值。
【讨论】:
您可以创建一个触发器来为您执行此操作。为确保触发器仅适用于克隆,您可以创建一个单独的用户名 CLONE 并使用它登录。或者,更好的是,如果您的 DBMS 支持它,创建一个名为 CLONE 的角色,任何用户都可以使用该角色登录并进行克隆。触发代码类似于:
if (CURRENT_ROLE = 'CLONE') then
new.ID = assign new id from generator/sequence
当然,您只会将该角色授予允许克隆记录的用户。
【讨论】: