SQL Server格式文件 - 我可以用来生成create table语句吗?

时间:2017-09-09 19:41:50

标签: sql-server xml reverse-engineering ddl bcp

我收到了35个SQL Server格式文件(包括xml和非xml)和相关的数据文件。我没有的是创建35个表所需的DDL。

有没有办法对格式文件进行反向工程以生成create table语句?我知道我可以查看每个文件并手动执行此操作,但尝试查看是否有更简单的方法...

感谢您提供的任何帮助

麦克

1 个答案:

答案 0 :(得分:0)

假设您的bcp xml格式文件看起来与此类似:

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <RECORD>
  <FIELD ID="1" xsi:type="NativeFixed" LENGTH="4"/>
  <FIELD ID="2" xsi:type="NativePrefix" PREFIX_LENGTH="1"/>
  <FIELD ID="3" xsi:type="CharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="3" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="4" xsi:type="CharPrefix" PREFIX_LENGTH="8" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="5" xsi:type="CharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="150" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="Id" xsi:type="SQLINT"/>
  <COLUMN SOURCE="2" NAME="Type" xsi:type="SQLSMALLINT"/>
  <COLUMN SOURCE="3" NAME="Language" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="4" NAME="Value" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="5" NAME="Subject" xsi:type="SQLVARYCHAR"/>
 </ROW>
</BCPFORMAT>

此sql脚本生成sql语句,以从bcp xml格式文件创建表。

declare @columns table(id INT NOT NULL, colName SYSNAME NOT NULL, dataType VARCHAR(50), [Length] INT NULL);
declare @filePath = 'C:\table.xml'
DECLARE @xmlData XML, @sqlCmd NVARCHAR(1000);
SET @sqlCmd = N'SET @xmlData = (
  SELECT * FROM OPENROWSET (
    BULK ''' + @filePath  + ''', SINGLE_BLOB
  ) AS xmlData
)';
EXEC sp_executesql @sqlCmd, N'@xmlData XML OUTPUT',@xmlData=@xmlData OUTPUT

;WITH XMLNAMESPACES 
(
    DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/bulkload/format',
    'http://www.w3.org/2001/XMLSchema-instance' as xsi
)
insert into @columns
SELECT  x.c.value('@SOURCE', 'INT'),
        x.c.value('@NAME', 'varchar(100)'),
        SUBSTRING(x.c.value('@xsi:type', 'varchar(100)'), 4, 20),
        ISNULL(y.f.value('@MAX_LENGTH', 'INT'), y.f.value('@LENGTH', 'INT'))
FROM @xmldata.nodes('/BCPFORMAT/ROW/COLUMN') x(c)
JOIN @xmldata.nodes('/BCPFORMAT/RECORD/FIELD') y(f) ON x.c.value('@SOURCE', 'INT') = y.f.value('@ID', 'INT')

UPDATE @columns SET dataType = REPLACE(dataType, 'VARYCHAR', 'VARCHAR');
UPDATE @columns SET dataType = REPLACE(dataType, 'DATETIM4', 'SMALLDATETIME');

declare @sql table(s varchar(1000), id int identity)

-- create statement
insert into  @sql(s) values ('create table [#myTable] (')

insert into  @sql(s)
    SELECT '  ['+[colName]+'] ' + [dataType] 
        + IIF([Length] IS NOT NULL AND [dataType] LIKE 'N%CHAR', '(' + CAST([Length]/2 AS VARCHAR) + ')', 
          IIF([Length] IS NOT NULL AND [dataType] LIKE '%CHAR', '(' + CAST([Length] AS VARCHAR) + ')', 
          IIF([Length] IS NULL AND [dataType] LIKE '%CHAR', '(MAX)', 
          '') ) ) + ','
    FROM @columns
    ORDER BY id;


    -- remove trailing comma
update @sql set s=left(s,len(s)-1) where id=@@identity

-- closing bracket
insert into @sql(s) values( ')' )

DECLARE @dmlQuery NVARCHAR(max) = ''
SELECT @dmlQuery += s FROM @sql ORDER BY id;
PRINT @dmlQuery -- sql query CREATE TABLE ….

然后您可以将其放入新创建的表中

BULK INSERT [#myTable] FROM 'C:\table.dat' WITH (KEEPIDENTITY, DATAFILETYPE='native', FORMATFILE = 'C:\table.xml');