我正在使用SSMS 2014和SQL Server 2014.我需要使用包含数据的excel文件或表来更改查询结果末尾的列名。
在一些SELECT语句之后,我得到一个包含数据的表格,例如
+---------+---------+------+
| Col1 | Col2 | Col3 |
+---------+---------+------+
| Value 1 | Value 2 | 123 |
| Value 2 | Value 2 | 456 |
| Value 3 | Value 3 | 789 |
+---------+---------+------+
表或excelfile
+----+---------+-----------+-----------+
| ID | ColName | Language | Addition |
+----+---------+-----------+-----------+
| 1 | Col1 | D | 123 |
| 2 | Col2 | D | 456 |
| 3 | Col3 | D | 789 |
| 4 | Col1 | E | 123 |
| 5 | Col2 | E | 456 |
| 6 | Col3 | E | 789 |
+----+---------+-----------+-----------+
我尝试做的是获取每列的添加值并将其添加到列名称中。它应该只添加具有特定language. @setLang = 'D'
Col1 + Addition
Col2 + Addition
Col3 + Addition
+-------------+-------------+---------+
| Col1 123 | Col2 456 | Col3789 |
+-------------+-------------+---------+
| Value 1 | Value 2 | 123 |
| Value 2 | Value 2 | 456 |
| Value 3 | Value 3 | 789 |
+-------------+-------------+---------+
我在Information_Schema.Columns上尝试过,并使用table =' resultTable'和Column_name = @cName。也许我需要一个循环来获取每个列名。
感谢阅读并试图帮助我。
答案 0 :(得分:1)
给它一个去 - 它使用一个表,而不是一个excel文件(但这似乎是你问题中的一个选项)。我已经制作了一些临时表格,并用你的价值观填充它们,但你显然不需要这样做。您需要将tempdb
的引用替换为保存表的数据库的名称,并将临时表#Original和#ExcelInfo替换为您的表名。
我还使用临时表将'Id IDENTITY(1,1)`列添加到包含原始数据的表中。这需要检查未开发的东西;如果你可以修改你的表以包含一个Id,这将使事情变得更容易,但如果没有,你可以像我一样插入临时表。
脚本比看起来短 - 整个第一位只是设置示例;真正的答案从声明语言变量的行开始。
/*
The script between the first two dividing lines of dashes is just used to set up the example. The bit you want is from
the "-- Test Variables --" line.
*/
-----------------------------------------------------------------------------------------------------------------------
IF OBJECT_ID('tempdb..#Original') IS NOT NULL DROP TABLE #Original
IF OBJECT_ID('tempdb..#ExcelInfo') IS NOT NULL DROP TABLE #ExcelInfo
CREATE TABLE #Original
( Col1 VARCHAR(50)
,Col2 VARCHAR(50)
,Col3 VARCHAR(50))
CREATE TABLE #ExcelInfo
( Id INT IDENTITY(1,1) NOT NULL
,ColName VARCHAR(50) NOT NULL
,[Language] CHAR(1) NOT NULL
,Addition INT NOT NULL)
INSERT #Original
SELECT *
FROM
( SELECT 'Value 1' AS Col1,'Value 2' AS Col2 ,123 AS Col3
UNION SELECT 'Value 2' ,'Value 2' ,456
UNION SELECT 'Value 3' ,'Value 3' ,789) AS This
ORDER BY Col1
INSERT #ExcelInfo (ColName,[Language],Addition)
SELECT *
FROM
( SELECT 'Col1' AS ColName, 'D' AS [Language], 123 AS Addition
UNION SELECT 'Col2','D',456
UNION SELECT 'Col3','D',789
UNION SELECT 'Col1','E',123
UNION SELECT 'Col2','E',456
UNION SELECT 'Col3','E',789) AS This
ORDER BY [Language], Addition
-----------------------------------------------------------------------------------------------------------------------
-- Test Variables --
DECLARE @SetLang CHAR(1) = 'D'
-----------------------------------------------------------------------------------------------------------------------
-- make the default empty, not null on our dynamic string, so it can be added to
DECLARE @Columns VARCHAR(MAX) = ''
DECLARE @SQL VARCHAR(MAX)
CREATE TABLE #OriginalColumns
( Id INT IDENTITY(1,1)
,Name VARCHAR(50))
CREATE TABLE #BasicResult
(Id INT NOT NULL, Name VARCHAR(50), Value VARCHAR(50))
-- If you can add an id column to your original table, this bit is unecessary - you can use yours in place of this table
CREATE TABLE #Original_WITH_Id
( Id INT IDENTITY(1,1)
,Col1 VARCHAR(50)
,Col2 VARCHAR(50)
,Col3 VARCHAR(50))
INSERT #Original_WITH_Id
SELECT * FROM #Original
-----------------------------------------------------------------------------------------------------------------------
-- List out the columns and put the list in a variable.
INSERT #OriginalColumns
SELECT QUOTENAME(Col.name)
FROM tempdb.sys.columns AS Col
WHERE Col.object_id = OBJECT_ID('tempdb.dbo.#Original_WITH_Id')
-- we're not interested in the identity column at the moment
AND Col.name <> 'Id'
-- keep everything in the same order as they are listed on the table
ORDER BY Col.column_id
SELECT @Columns = @Columns + ',' + Name
FROM #OriginalColumns
-- clip off the leading comma
SELECT @Columns = SUBSTRING(@Columns,2,LEN(@Columns))
-- get a full list of everything, creating our new list of columns as we go, using the Id column to keep a mark on which
-- row each record originally came from
SET @SQL =
'INSERT #BasicResult
SELECT Id, New.Name, Value FROM
(SELECT Id, Name, Value
FROM #Original_WITH_Id
UNPIVOT (Value FOR Name IN (' + @Columns + ')) Unpvt) AS Old
JOIN (SELECT ColName, CONVERT(VARCHAR(50),ColName) + '' '' + CONVERT(VARCHAR(50),Addition) AS Name
FROM #ExcelInfo
WHERE [Language] = ''' + @SetLang + ''') AS New ON Old.Name = New.ColName'
PRINT @SQL
EXEC (@SQL)
-- now update our list of columns to be the new column headings
SET @Columns = ''
SELECT @Columns = @Columns + ',' + QUOTENAME(Name) FROM (SELECT DISTINCT Name FROM #BasicResult) AS Names
SELECT @Columns = SUBSTRING(@Columns,2,LEN(@Columns))
-- pivout our results back out to their original format, but with the new column headings (include the Id if you want)
SET @SQL =
'SELECT /*Id,*/ ' + @Columns + '
FROM
(SELECT Id, Name,Value
FROM #BasicResult) AS Up
PIVOT (MAX(Value) FOR Name IN (' + @Columns + ')) AS Pvt'
PRINT @SQL
EXEC (@SQL)
-- clean up --
DROP TABLE #OriginalColumns
DROP TABLE #BasicResult
希望有所帮助!可能有一种更有效的方法来做到这一点......我不确定。
答案 1 :(得分:0)
好的我再试一次,但现在没有Excelfile。我从Excelfile中创建了一个CSV并将其与Bulk一起插入到我创建的表中:
IF NOT EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'CSVTest')
BEGIN
CREATE TABLE _DICTIONARY
( _TableName VARCHAR (20),
_ColumnName VARCHAR (20),
_Language VARCHAR (20),
_FieldShort VARCHAR (50),
_FieldMid VARCHAR (50),
_FieldLong VARCHAR (50)
)
BULK
INSERT _DICTIONARY
FROM 'C:\_DICTIONARY.csv'
WITH
(
FIELDTERMINATOR = ';',
ROWTERMINATOR = '\n'
)
END
之后,我使用Cursor重命名所有列
DECLARE @dic_tableName as nvarchar(50),
@dic_columnName as nvarchar(50),
@db_tableName as nvarchar(50),
@db_columnName as nvarchar(50);
DECLARE C CURSOR FAST_FORWARD FOR
SELECT _TableName, _ColumnName FROM _DICTIONARY
OPEN C;
FETCH NEXT FROM C INTO @dic_tableName, @dic_columnName;
WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS(SELECT TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @dic_tableName AND COLUMN_NAME = @dic_columnName)
BEGIN
SET @db_tableName = @dic_tableName + '.' + @dic_columnName
SET @db_columnName = @dic_tableName + '_' + @dic_columnName
EXEC sp_rename @db_tableName, @db_columnName ,'COLUMN'
FETCH NEXT FROM C INTO @dic_tableName, @dic_columnName;
END
ELSE
BEGIN
FETCH NEXT FROM C INTO @dic_tableName, @dic_columnName;
END
END
CLOSE C;
DEALLOCATE C;
它的工作。