使用Server 2008,我想复制表的一行,而不知道字段名。我的关键问题是:随着时间的推移,表会不断增长和变异,我希望这个拷贝脚本能够继续工作,而不必写出不断变化的30+字段,嗯。
当然,问题还在于标识字段不能复制。
我下面的代码确实有效,但是我想知道是否有比我抛出的文本字符串SQL语句更合适的方法?
所以提前谢谢你。这是我的(是的,工作的)代码-我欢迎关于改进它的建议。托德
alter procedure spEventCopy
@EventID int
as
begin
-- VARS...
declare @SQL varchar(8000)
-- LIST ALL FIELDS (*EXCLUDE* IDENTITY FIELDS).
-- USE [BRACKETS] FOR ANY SILLY FIELD-NAMES WITH SPACES, OR RESERVED WORDS...
select @SQL = coalesce(@SQL + ', ', '') + '[' + column_name + ']'
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'EventsTable'
and COLUMNPROPERTY(OBJECT_ID('EventsTable'), COLUMN_NAME, 'IsIdentity') = 0
-- FINISH SQL COPY STATEMENT...
set @SQL = 'insert into EventsTable '
+ ' select ' + @SQL
+ ' from EventsTable '
+ ' where EventID = ' + ltrim(str(@EventID))
-- COPY ROW...
exec(@SQL)
-- REMEMBER NEW ID...
set @EventID = @@IDENTITY
-- (do other stuff here)
-- DONE...
-- JUST FOR KICKS, RETURN THE SQL STATEMENT SO I CAN REVIEW IT IF I WISH...
select EventID = @EventID, SQL = @SQL
end发布于 2012-06-24 21:00:40
不,没有任何神奇的方法可以说“选择除<foo>之外的所有列”--您正在做的方式是您必须如何做(另一个答案中的黑客)。
下面是我如何使用这些更改来修改您的代码(有些是超链接的,这样您就可以了解我对原因的看法):
INFORMATION_SCHEMA.COLUMNSnvarchar而不是varchar@@identityexecstuff而不是coalesceSET NOCOUNT ONQUOTENAME,因为它比'[' + ... + ']'更安全ALTER PROCEDURE dbo.spEventCopy
@EventID INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += ',' + QUOTENAME(name)
FROM sys.columns
WHERE [object_id] = OBJECT_ID('dbo.EventsTable')
AND is_identity = 0;
SET @sql = STUFF(@sql, 1, 1, '');
SET @sql = N'INSERT dbo.EventsTable(' + @sql + ')
SELECT ' + @sql + ' FROM dbo.EventsTable
WHERE EventID = ' + CONVERT(VARCHAR(12), @EventID) + ';';
EXEC sp_executesql @sql;
SELECT @EventID = SCOPE_IDENTITY();
-- do stuff with the new row here
SELECT EventID = @EventID, SQL = @SQL;
END发布于 2012-06-24 21:00:14
如果您知道您的身份列被称为什么(而且它不会更改列),您可以这样做:
SELECT * INTO #dummy FROM EventsTable where EventID = @EventID;
ALTER TABLE #dummy
DROP COLUMN MyIdentityColumn
INSERT EventsTable SELECT * FROM #dummy
DROP TABLE #dummy由于表只能有一个标识列,所以在查询中指定这一点不应该对您造成太大的限制。
正如Aaron Bertrand指出的那样,这种方法存在风险。请阅读以下评论中的讨论。
https://stackoverflow.com/questions/11181064
复制相似问题