2010-07-14 3 views
3

Я знаю, что этот вопрос мог пройти несколько раз здесь, но я действительно не нашел обходного пути. Также мой вопрос может быть немного иным.повторяющаяся строка - выберите все столбцы, кроме одного

Ситуация: У меня есть таблица с 130 столбцами (+100.000 строк), а количество столбцов будет даже увеличиваться в будущем. По этой причине я хотел бы определить выбор столбцов как [выбрать все, кроме одного]

AS Я хочу дублировать строку с помощью [выбрать все] Я получаю сообщение об ошибке на первичный ключ -> nc_ID, потому что - конечно, он пытается дублировать это значение, а не увеличивать его на единицу.

Очевидно, что столбец, который я хочу исключить из выделения, является первым, nc_ID. Я читал и слышал, что такие решения [выбрать все, кроме одного] можно выполнить только с помощью динамического sql. Если бы кто-нибудь мог объяснить мне через кусок, если код sql?

INSERT into TableName (all columns except the first *nc_ID*) Select * From TableName Where nc_ID=12345;

Заранее спасибо!

+2

ничего себе - у вас есть таблица с 130 столбцами, будет увеличиваться! Извините, но ничего себе .... – Rippo

+0

Я знаю, мы должны подумать о нормализации этой таблицы ... Кстати, это 175 колоний. // Спасибо за все ваши комментарии – laurens

+0

Возможный дубликат [SQL исключить столбец с помощью SELECT \ * \ [except columnA \] FROM tableA?] (Http://stackoverflow.com/questions/729197/sql-exclude-a -column-using-select-except-columna-from-tablea) – zloctb

ответ

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',@[email protected]_ID 
+0

Это то, что мне нужно! Просто вставил мой TableName, и все было сделано. Благодаря!! ура – laurens

0

Вы должны написать код, чтобы вручную заполнить имена столбцов. SQL не поддерживает «все столбцы, кроме».

130 колонн граничат с сумасшедшими, и тот факт, что количество столбцов увеличивается, говорит мне, что вы должны действительно сесть и рассмотреть вашу схему. Этот может быть в норме для денормализованной таблицы в стиле хранилища данных, но даже я настоятельно рекомендую сесть и дать вашей схеме хорошее мнение и убедиться, что нет лучшего способа обойти вещи.

+0

У ОП, вероятно, есть требование для полей, заданных пользователем. –

2

Вам необходимо будет enumerate the list of columns.

После этого вам необходимо будет identify the identity column, чтобы вы могли исключить его из списка столбцов.

Из соображений безопасности (чтобы избежать инъекции SQL), вы должны использовать оставшийся список столбцов для build up a parameter set для выполнения вашей вставки.

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 
+0

Предполагая, что 'nc_id' является столбцом' identity', это не будет работать без 'identity_insert'. Если вы включите 'identity_insert', вы выбросите все преимущества наличия столбца« identity »(и это будет очень плохая идея). – Donnie

+0

Это общий подход, который я бы предложил. Попробуйте установить nc_ID в значение null (в таблице temp). BTW, SQL-программирование имеет тенденцию быть утомительным, а не сложным. Если вы чувствуете необходимость быть действительно умным, вы, вероятно, не замечаете более прозаического подхода. – SeaDrive

+1

С другой стороны, вам может понадобиться сделать DROP COLUMN в таблице temp, чтобы избавиться от столбца идентификации. – SeaDrive

0

При использовании конструктора запросов в Managment Studio, и вы делаете простой запрос, как

SELECT * FROM Table 

Студия управления переписывает SQL явно назвать все столбцы , Затем вы можете удалить PK из этого списка.

Если вы сделаете запрос «выберите все, кроме PK», и используете его из всех других запросов, у вас есть только один запрос для обновления.

Смежные вопросы