我知道这个问题可能已经过了几次,但我还没有找到任何解决方法。我的问题也可能有点不同。
情况是:我有一个包含130列(+100.000行)的表,并且将来会增加列数。出于这个原因,我想将列的选择定义为[select all but one]
我想用[全部选择]复制一行我在主键上收到错误 - > nc_ID因为 - 当然 - 它也试图复制这个值,而不是将它增加一个。
很明显,我想从选择中排除的列是第一个,即nc_ID。我读到并听说只有动态sql才能完成这种[select all but one]解决方案。如果是这样,有人可以通过sql代码解释我吗?
INSERT into TableName (all columns except the first *nc_ID*)
Select * From TableName Where nc_ID=12345;
提前致谢!
答案 0 :(得分:2)
您需要enumerate the list of columns。
然后您必须identify the identity column,以便将其从列表中排除。
出于安全原因(为了避免SQL注入),您应该使用build up a parameter set的剩余列列表来执行插入。
答案 1 :(得分:2)
怎么样:
SELECT * INTO #MYTEMP FROM TableName WHERE nc_ID = 12345
UPDATE #MYTEMP SET nc_ID = nc_ID + 1; -- or some other calculation or queried value
INSERT INTO TableName
SELECT * FROM #MYTEMP
DROP TABLE #MYTEMP
答案 2 :(得分:2)
您是否在动态SQL中询问如何执行此操作? - 以下内容应该有效。
(The Curse and Blessings of Dynamic SQL的强制性链接)
DECLARE @TableName varchar(500)
DECLARE @nc_ID INT
SET @nc_ID = 12345
SET @TableName = '[dbo].[TableName]'
DECLARE @Dynsql nvarchar(max)
SELECT @Dynsql = ISNULL(@Dynsql + ',','') + QUOTENAME(name) FROM sys.columns
WHERE object_id = object_id(@TableName) and is_identity = 0 and is_computed = 0
ORDER BY column_id
IF @@ROWCOUNT=0
RAISERROR('%s not found in sys.columns',16,1, @TableName)
SET @Dynsql = 'INSERT INTO ' + @TableName + '
('+ @Dynsql +')
SELECT '+ @Dynsql +'
FROM ' + @TableName + '
WHERE nc_ID = @nc_ID'
EXEC sp_executesql @Dynsql, N'@nc_ID int',@nc_ID=@nc_ID
答案 3 :(得分:0)
您必须编写代码以手动填充列名称。 SQL不支持“除”之外的所有列。
130列正在疯狂,列数增加的事实告诉我你应该坐下来考虑你的架构。这个可能对于数据仓库样式的非规范化表是可以的,但是我仍然强烈建议坐下来给你的架构一个好的思考,并确保没有(更多)更好的方式去做的东西。
答案 4 :(得分:0)
在Managment Studio中使用查询设计器时,您可以进行简单的查询,如
SELECT * FROM Table
管理工作室重写SQL以显式命名所有列。然后,您可以从该列表中删除PK。
如果您将其作为“选择除PK以外的所有”查询,并在所有其他查询中使用此查询,那么您只需要一个查询即可更新。