Excel工作表中的SQL列名称

时间:2014-10-24 12:07:04

标签: sql excel ssms sql-server-2014-express

我正在使用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。也许我需要一个循环来获取每个列名。

感谢阅读并试图帮助我。

2 个答案:

答案 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;

它的工作。