未在T-SQL中创建动态列

时间:2013-06-11 05:44:04

标签: sql sql-server sql-server-2008 tsql

我有以下表格:

tblengineeringlookupcolumnmaster

elccolumnid | elclookupcode | elccolumnname | elcisrequired

1             |   64              |   FirstName |      1
2             |   64              |   LastName  |      1
3             |   65              |   abc       |      1
4             |   65              |   xyz       |      1

tblengineeringlookupdetail

eldrecordId | eldlookupcode |eldlookupsequence |eldlookupvalue | eldlookupvaluedescription

245     |     64        |    0         |   Red        |    Aravinth,Arumugam

246     |     64        |    1         |   Blue       |    Santhosh,Chandran

247     |     64        |    2         |   Green          |  Karthik,Balasubramanian

当我将'64'作为参数传递给程序时。 我得到的输出为:

FirstName | LastName        | eldRecordId  
-------------------------------------
Aravinth  |  Arumugam       | 245        
Santhosh  |  Chandran       | 246
Karthik   |  Balasubramanian| 247

使用的商店程序是

// SP

-- Select the columns to be used
DECLARE @tcol TABLE
(
      ID INT IDENTITY(1,1)
    , elclookupcode INT
    , elccolumnname VARCHAR(100)
)
-- Insert the records into the table
INSERT INTO @tcol (elclookupcode, elccolumnname)
SELECT elclookupcode,elccolumnname FROM tblEngineeringLookupColumnMaster WHERE elclookupcode=@LookupCode

-- Select the columns which should be as output as a table
DECLARE @temp TABLE
(
        elcLookupCode INT
      , RecordId INT
      , txt VARCHAR(8000)
)

-- Select the records from the table and insert
INSERT INTO @temp (elcLookupCode, RecordId, txt)
SELECT eldLookupCode,eldRecordId, eldLookupValueDescription FROM tblEngineeringLookupDetail WHERE eldLookupCode=@LookupCode

DECLARE @SQL NVARCHAR(MAX)

-- Have a table for the selected values
;WITH cte AS 
(
    SELECT 
          token = ', [' + d2.elccolumnname + '] = ''' + d.token + ''''
        , d.RecordId
    FROM (
        SELECT 
              token = t.c.value('.', 'VARCHAR(50)')
            , a.RecordId
            , a.elcLookupCode
            , rn = ROW_NUMBER() OVER (PARTITION BY a.RecordId ORDER BY a.RecordId)
        FROM (
            SELECT 
                  RecordId
                , elcLookupCode
                , txml = CAST('<t>' + REPLACE(txt, ',', '</t><t>') + '</t>' AS XML)
            FROM @temp
        ) a
        CROSS APPLY txml.nodes('/t') t(c)
    ) d
    -- Select the columns to be mapped
   JOIN (
        SELECT 
              elclookupcode
            , elccolumnname
            , rn = ROW_NUMBER() OVER (PARTITION BY elclookupcode ORDER BY elclookupcode) 
        FROM @tcol 
    ) d2 ON d.elcLookupCode = d2.elclookupcode AND d2.rn = d.rn
)
-- Join all the records taken
SELECT @SQL = STUFF((
        SELECT CHAR(13) + 'UNION ALL SELECT  '+ STUFF((
        SELECT t2.token
        FROM cte t2
        WHERE t2.RecordId = t.RecordId
        FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, ''), ',[RecordId] = ' + CAST(RecordId AS VARCHAR(10)) 
        FROM @temp t
    FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 11, '')

PRINT @SQL
EXEC sp_executesql @SQL
END

现在的问题是:

如果我将'65'作为参数传递给过程,那么第一个表中存在值(tblengineeringlookupcolumnmaster)并且第二个表中没有相应的值(tblengineeringlookupdetail)我得不到结果(显示3rows affected的消息)。

但我必须单独获取columns标题。

“样品:

xyz  | abc  | eldrecordId

NULL |NULL | NULL

为什么我没有得到这个?哪里我错了?

1 个答案:

答案 0 :(得分:1)

试试这个 -

DECLARE @tcol TABLE
(
      ID INT IDENTITY(1,1)
    , elclookupcode INT
    , elccolumnname VARCHAR(20)
)

INSERT INTO @tcol (elclookupcode, elccolumnname)
VALUES 
    (65, 'FirstName'),
    (65, 'LastName')

DECLARE @temp TABLE
(
        elcLookupCode INT
      , eldRecordId INT
      , txt VARCHAR(100)
)

INSERT INTO @temp (elcLookupCode, eldRecordId, txt)
VALUES 
    (64, 245, 'Aravinth,Arumugam'),
    (64, 246, 'Santhosh,Chandran'),    
    (64, 247, 'Karthik,Balasubramanian')

DECLARE @SQL NVARCHAR(MAX)

;WITH cte AS 
(
    SELECT 
          token = ', [' + d2.elccolumnname + '] = ''' + d.token + ''''
        , d.eldRecordId
    FROM (
        SELECT 
              token = t.c.value('.', 'VARCHAR(50)')
            , a.eldRecordId
            , a.elcLookupCode
            , rn = ROW_NUMBER() OVER (PARTITION BY a.eldRecordId ORDER BY a.eldRecordId)
        FROM (
            SELECT 
                  eldRecordId
                , elcLookupCode
                , txml = CAST('<t>' + REPLACE(txt, ',', '</t><t>') + '</t>' AS XML)
            FROM @temp
        ) a
        CROSS APPLY txml.nodes('/t') t(c)
    ) d
    LEFT JOIN (
        SELECT 
              elclookupcode
            , elccolumnname
            , rn = ROW_NUMBER() OVER (PARTITION BY elclookupcode ORDER BY elclookupcode) 
        FROM @tcol 
    ) d2 ON d.elcLookupCode = d2.elclookupcode AND d2.rn = d.rn
)
SELECT @SQL = STUFF((
        SELECT CHAR(13) + 'UNION ALL SELECT [eldRecordId] = ' + CAST(eldRecordId AS VARCHAR(10)) + ', ' + 
           '[elcLookupCode] = ' + CAST(elcLookupCode AS VARCHAR(10)) + ISNULL(STUFF((
        SELECT t2.token
        FROM cte t2
        WHERE t2.eldRecordId = t.eldRecordId
        FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, ', '), '')
        FROM @temp t
    FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 11, '')

PRINT @SQL
EXEC sys.sp_executesql @SQL