根据其他 table 的内容创建 table
Create tables based on contents of other table
我有一个 table,其中包含要创建的 table 的名称以及 table 应该具有的列:
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 中的每个 table 动态创建 tables 并且拆分字段 column_names 来决定哪些列每个 table 应该有。所有字段都可以是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;
我有一个 table,其中包含要创建的 table 的名称以及 table 应该具有的列:
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 中的每个 table 动态创建 tables 并且拆分字段 column_names 来决定哪些列每个 table 应该有。所有字段都可以是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;