Как я могу сбросить все столбцы в таблице за порядковый номер х в 0? - PullRequest
1 голос
/ 19 августа 2011

Давайте представим, что я хочу установить для всех столбцов после первого идентификатора столбца значение 0 и что имена столбцов в таблице, которые я хотел бы сбросить, определены в другой таблице. Для иллюстрации давайте представим, что я работаю с различными валютами, как определено в таблице #tmpFX. Что такое команда SQL 2005 UPDATE, которая позволяет мне устанавливать gbp, eur, jpy и usd равными 0, где ID = 2 на основе (SELECT * from #tmpFX), который идентифицирует столбцы, которые необходимо обновить?

use tempdb
GO
CREATE TABLE #tmpFX(iso_code VARCHAR(3))
INSERT #tmpFX VALUES('gbp')
INSERT #tmpFX VALUES('eur')
INSERT #tmpFX VALUES('jpy')
INSERT #tmpFX VALUES('usd')
SELECT * FROM #tmpFX

CREATE TABLE #tmpCashVal (id INT, gbp REAL, eur REAL, jpy REAL, usd REAL)
INSERT #tmpCashVal VALUES (1, 0, 0, 0, 1000)
INSERT #tmpCashVal VALUES (2, 0, 0, 2000, 0)
INSERT #tmpCashVal VALUES (3, 500, 0, 0, 0)

SELECT * FROM #tmpFX
SELECT * FROM #tmpCashVal

DROP TABLE #tmpFX
DROP TABLE #tmpCashVal

т.е. строка 2 #tmpCashVal будет читать после команды UPDATE:

id  gbp eur jpy usd
2   0   0   0   0

Большое спасибо, Берти.

Ответы [ 3 ]

0 голосов
/ 19 августа 2011

Нет стандартного синтаксиса, позволяющего ссылаться на столбцы по их порядковым позициям, в любом случае, не в Transact-SQL.

Вы можете получить информацию о порядковых позициях столбцов, запросив INFORMATION_SCHEMA.COLUMNS, хоть.И если ваш запрос действительно должен быть основан на порядковых позициях столбцов, вам нужно создать динамический запрос и предоставить ему правильные имена столбцов для ссылки.Примерно так, возможно:

DECLARE @sql varchar(max), @Columns varchar(max), @TableName sysname;
SET @TableName = '<i>you table name</i>';

SELECT @Columns = COALESCE(@Columns + ', ', '') + QUOTENAME(COLUMN_NAME) + ' = 0'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TableName
  AND ORDINAL_POSITION > <i>the specified position</i>;

SET @sql = 'UPDATE ' + QUOTENAME(@TableName) + ' SET ' + @Columns + ' WHERE ID = 2';

PRINT @sql;
-- EXEC(@sql);
0 голосов
/ 19 августа 2011

Надеюсь, это поможет ...

use tempdb
GO
CREATE TABLE #tmpFX(iso_code VARCHAR(3))
INSERT #tmpFX VALUES('gbp')
INSERT #tmpFX VALUES('eur')
INSERT #tmpFX VALUES('jpy')
INSERT #tmpFX VALUES('usd')
SELECT * FROM #tmpFX

CREATE TABLE #tmpCashVal (id INT, gbp REAL, eur REAL, jpy REAL, usd REAL)
INSERT #tmpCashVal VALUES (1, 0, 0, 0, 1000)
INSERT #tmpCashVal VALUES (2, 0, 0, 2000, 0)
INSERT #tmpCashVal VALUES (3, 500, 0, 0, 0)

SELECT * FROM #tmpFX
SELECT * FROM #tmpCashVal

DECLARE @ID AS INT = 2

DECLARE @Update_Cols AS NVARCHAR(MAX) = ''
DECLARE @SqlText AS NVARCHAR(MAX) = ''

SELECT @Update_Cols = @Update_Cols + '[' + iso_code + '] = 0,' FROM #tmpFX

SELECT @Update_Cols AS 'Cols'

SELECT @Update_Cols = LEFT(@Update_Cols, CASE WHEN LEN(@Update_Cols) > 0 THEN LEN(@Update_Cols) - 1 ELSE 0 END)

--Do only if atleast one row exists in the table #tmpFX
IF LEN(@Update_Cols) > 0 
BEGIN
    SELECT @SqlText = 'UPDATE #tmpCashVal SET ' + @Update_Cols + ' WHERE ID = @ID'
    EXEC sp_executesql @SqlText, N'@ID INT', @ID = @ID
END
SELECT * FROM #tmpCashVal

DROP TABLE #tmpFX
DROP TABLE #tmpCashVal
0 голосов
/ 19 августа 2011

Это поможет:

--This bit puts everything in one string
DECLARE @Columns VARCHAR(MAX)
SELECT @Columns = COALESCE(@Columns + ' = 0, ', '') + iso_code FROM #tmpFX
SET @Columns = @Columns + ' = 0'

--Build our query string
DECLARE @Query VARCHAR(MAX)
SET @Query = 'UPDATE #tmpCashVal SET ' + @Columns + ' WHERE id = 2'

EXEC(@Query)

Очевидно, что вы можете изменить строку @Query так, чтобы она в этот момент делала все, что вам нравится.

Вы также можете сделать это с помощью курсоравыбирая каждое значение из #tmpFX по очереди и используя динамический SQL для его выполнения, как здесь, но, очевидно, вы платите за это снижение производительности.

Подробнее о размещении всех столбцов в одну строку,см. Объединить много строк в одну текстовую строку?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...