微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

根据其他表的内容创建表

如何解决根据其他表的内容创建表

我有一个表,其中包含要创建的表的名称以及该表应具有的列:

CREATE TABLE Tables2Create (
table_name nvarchar(256),colum_names nvarchar(max)
)
INSERT INTO Tables2Create VALUES ('People','Name|Occupation|Hobby')
INSERT INTO Tables2Create VALUES ('Schools','Name|Place|Type ')

现在我需要一些 Tsql,它会为字段 table_names 中的每个表动态创建表,并拆分字段 column_names 以决定每个表应该包含哪些列。所有字段都可以是 nvarchar 的。

CREATE TABLE People (
Name nvarchar(256),Occupation nvarchar(256),Hobby nvarchar(256)
)

知道怎么做吗?

解决方法

以下是使用 STRING_SPLIT 提取列名并使用 STRING_AGG 连接列名和 CREATE TABLE 语句的示例。

DECLARE @SQL nvarchar(MAX);
SELECT @SQL = STRING_AGG(CreateTableStatement,'')
FROM (
    SELECT 
        'CREATE TABLE ' + QUOTENAME(table_name) + N' (' + 
        (
            SELECT STRING_AGG(QUOTENAME(value) + ' nvarchar(256)',',')
            FROM STRING_SPLIT(column_names,'|')
        )
        + N');'
    FROM dbo.Tables2Create
) AS CreateTableStatements(CreateTableStatement)

EXEC(@SQL);
,

你能做到吗?是的你可以。你应该?可能不会,如果我诚实的话。正如我在评论中提到的,存储分隔数据始终是一个设计缺陷;至少标准化你的设计。

话虽如此,我在这里使用的方法是“多合一”解决方案;没有游标,没有迭代。正如您标记了 SQL Server 2019,这意味着我们可以使用 STRING_AGG。这给出了这样的东西:

USE master;
GO

CREATE DATABASE TestDB;
GO

USE TestDB;
GO

CREATE TABLE Tables2Create (table_name sysname,--correct data type for object names
                            column_names nvarchar(max)
)
INSERT INTO Tables2Create VALUES (N'People',N'Name|Occupation|Hobby')
INSERT INTO Tables2Create VALUES (N'Schools',N'Name|Place|Type ');
GO

DECLARE @SQL nvarchar(MAX),@CRLF nchar(2) = NCHAR(13) + NCHAR(10);

DECLARE @Delim nvarchar(10) = N',' + @CRLF + N'    '

SET @SQL = (SELECT STRING_AGG(S.SQL,'')
            FROM(SELECT @CRLF + @CRLF +
                        N'CREATE TABLE dbo.' + QUOTENAME(T2C.table_name) + N' (' + @CRLF + N'    ' +
                        STRING_AGG(QUOTENAME(SS.value) +  N' nvarchar(256)',@Delim) WITHIN GROUP (ORDER BY SS.[Value]) + @CRLF + N');' AS SQL
                 FROM dbo.Tables2Create T2C
                      CROSS APPLY STRING_SPLIT(T2C.column_names,N'|') SS
                 GROUP BY T2C.table_name) S);

PRINT @SQL; --Your best friend

EXEC sys.sp_executesql @SQL;
GO

USE master;
GO

DROP DATABASE TestDB;

db<>fiddle

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。