如何将表中的所有列重置到序号位置x到0之外?

时间:2011-08-19 16:34:55

标签: sql sql-server tsql sql-server-2005 sql-update

让我们想象一下,我想将第一列id之后的所有列设置为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

即。 #tmpCashVal的第2行将在UPDATE命令之后读取:

id  gbp eur jpy usd
2   0   0   0   0

非常感谢, 贝尔蒂。

3 个答案:

答案 0 :(得分:0)

这样可以解决问题:

--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执行此操作,但显然您需要支付性能损失。

有关将所有列放入一个字符串的更多信息,请参阅Concatenate many rows into a single text string?

答案 1 :(得分:0)

没有标准语法允许您按顺序位置引用列,而不是在Transact-SQL中引用列。

可以通过查询INFORMATION_SCHEMA.COLUMNS获取有关列的序号位置的信息。如果您的查询确实必须围绕列序号位置建立,则需要构建动态查询并为其提供正确的列名以供参考。这样的事情,可能是:

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

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

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

PRINT @sql;
-- EXEC(@sql);

答案 2 :(得分:0)

希望这会有所帮助......

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