使用数据行从选择列创建表

时间:2019-03-25 20:26:28

标签: sql sql-server stored-procedures

我需要使用另一个表的行作为列名来创建一个表。原因是我的数据库不是关系数据库,因此,在每种情况下,我都有一个包含数据的表,另一个具有对应的元数据的表。

示例:

Table 1:

Person
ID | Info
===================================================
1  | <John Smith><1st Avenue><Miami,Florida><33101>
2  | <Mary Walton><83th Street><New York, NY><1001>

Table 2: 

Person_Desc
Field   | Info
===================================================
ID      | Sequential identifier
Name    | Persons full name
Address | Physical location detail
City    | City
ZIP_C   | Postal office code

我想创建一个存储过程,以接收这两个表名作为参数,并创建第三个表,就像这样(请忍受我和伪代码):

CREATE STORED PROCEDURE sp_relationalTable 
@dataTable nvarchar(50), 
@metadataTable nvarchar(50) , 
@TmpTable nvarchar(50)

    AS

    SELECT * FROM @metadataTable 

    CREATE TABLE @TmpData 
( @metadataTable_Field1 nvarchar(100), 
 ,@metadataTable_Field2 nvarchar(100),
 ,@metadataTable_Field3 nvarchar(100)....
)

    END

那是第一部分。然后,我对表1:人员运行SELECT语句,用已知的定界符将数据破坏,并将所有数据INSERT插入新创建的表中。

INSERT INTO @TmpData (SELECT * FROM @dataTable)

理想情况下,可以像我一开始所说的那样将其全部运行到一个SP中,因此,当您运行这样的SP时,就像:

EXEC sp_relationalTable Person, Person_Desc, RPerson

最后我会得到:

Table 3: 

RPerson
ID | Name        | Address       | City          | ZIP_C   |
============================================================
1  | John Smith  | 1st Avenue    | Miami,Florida |33101    |
2  | Mary Walton | 83th Street   | New York, NY  |1001     |

1 个答案:

答案 0 :(得分:0)

可能对您有帮助。根据表名更改代码。

DECLARE @TABLE TABLE (
    ID INT IDENTITY(1, 1)
    ,Info VARCHAR(MAX)
    )

INSERT INTO @TABLE
VALUES ('<John Smith><1st Avenue><Miami,Florida><33101>')

INSERT INTO @TABLE
VALUES ('<Mary Walton><83th Street><New York, NY><1001>')

SELECT ID
    ,MAX(CASE 
            WHEN RNO = 1
                THEN INFO
            ELSE ''
            END) AS [PERSON]
    ,MAX(CASE 
            WHEN RNO = 2
                THEN INFO
            ELSE ''
            END) AS [Address]
    ,MAX(CASE 
            WHEN RNO = 3
                THEN INFO
            ELSE ''
            END) AS [City]
    ,MAX(CASE 
            WHEN RNO = 4
                THEN INFO
            ELSE ''
            END) AS [ZIP_C]
FROM (
    SELECT ID
        ,REPLACE(VALUE, '<', '') INFO
        ,ROW_NUMBER() OVER (
            PARTITION BY ID ORDER BY ID
            ) RNO
    FROM @TABLE
    CROSS APPLY string_split(Info, '>')
    WHERE VALUE <> ''
    ) A
GROUP BY ID