0

我使用的是 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 上进行了尝试,并使用 where table = 'resultTable' 和 Column_name = @cName 进行过滤。也许我需要一个循环来获取每个列名。

感谢您阅读并尝试帮助我。

4

2 回答 2

1

试一试 - 它使用表格,而不是 excel 文件(但这似乎是您问题中的一个选项)。我已经制作了一些临时表并用您的值填充它们,但您显然不需要这样做。您需要用tempdb保存表的数据库名称替换对 的引用,用表名替换临时表 #Original 和 #ExcelInfo 。

我还使用临时表将“Id IDENTITY(1,1)”列添加到保存原始数据的表中。这是控制 unpivot 所必需的;如果您可以修改您的表以包含一个 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

希望有帮助!可能有更有效的方法来做到这一点......我不确定。

于 2014-10-24T15:47:49.267 回答
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

之后,我使用光标重命名所有列

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;

它在做它的工作。

于 2014-10-27T09:13:54.267 回答