2015-11-10 2 views
1

Это более теоретический вопрос, поскольку я не могу использовать его в это время. Но можете ли вы CREATE TABLE из XML. Например, если я бегуМожете ли вы создать таблицу из XML

select TABLE_CATALOG AS '@number', 
* from INFORMATION_SCHEMA.COLUMNS 
order by 1 
For XML Path ('root') 

Я получаю XML отсчет, как это для каждого типа данных в таблице

<root number="testdb"> 
    <TABLE_CATALOG>testdb</TABLE_CATALOG> 
    <TABLE_SCHEMA>dbo</TABLE_SCHEMA> 
    <TABLE_NAME>tb_Population</TABLE_NAME> 
    <COLUMN_NAME>ID</COLUMN_NAME> 
    <ORDINAL_POSITION>1</ORDINAL_POSITION> 
    <IS_NULLABLE>YES</IS_NULLABLE> 
    <DATA_TYPE>varchar</DATA_TYPE> 
    <CHARACTER_MAXIMUM_LENGTH>6</CHARACTER_MAXIMUM_LENGTH> 
    <CHARACTER_OCTET_LENGTH>6</CHARACTER_OCTET_LENGTH> 
    <CHARACTER_SET_NAME>iso_1</CHARACTER_SET_NAME> 
    <COLLATION_NAME>SQL_Latin1_General_CP1_CS_AS</COLLATION_NAME> 
</root> 

Могу ли я взять этот XML и сделать что-то вроде этого

CREATE TABLE [dbo].[xmlTest] 
From declare @XML xml = 
    '<root number="testdb"> 
     <TABLE_CATALOG>testdb</TABLE_CATALOG> 
     <TABLE_SCHEMA>dbo</TABLE_SCHEMA> 
     <TABLE_NAME>tb_Population</TABLE_NAME> 
     <COLUMN_NAME>ID</COLUMN_NAME> 
     <ORDINAL_POSITION>1</ORDINAL_POSITION> 
     <IS_NULLABLE>YES</IS_NULLABLE> 
     <DATA_TYPE>varchar</DATA_TYPE> 
     <CHARACTER_MAXIMUM_LENGTH>6</CHARACTER_MAXIMUM_LENGTH> 
     <CHARACTER_OCTET_LENGTH>6</CHARACTER_OCTET_LENGTH> 
     <CHARACTER_SET_NAME>iso_1</CHARACTER_SET_NAME> 
     <COLLATION_NAME>SQL_Latin1_General_CP1_CS_AS</COLLATION_NAME> 
    </root>' 

Очевидно, что это совсем не правильно, но вы получаете эту идею. Я просто хочу знать, можно ли буквально запустить инструкцию create table для xml. Я мог видеть, что это используется, возможно, если вы хотите воссоздать структуру таблицы из одного db в другой, но они являются разрозненными системами или что-то в этом роде. Или, может быть, я не знаю, о чем, черт возьми, я тоже говорю :-)

+0

Используете ли вы SQL Server или MySQL? Основываясь на коде, я думаю, что это синтаксис TSQL? – lad2025

+0

Создать: не то, что я мог найти. Нагрузка: да. [MySQL: load-xml] (https://dev.mysql.com/doc/refman/5.5/en/load-xml.html) – Alderin

ответ

2

Этот вопрос предназначен для меня заново изобретать колесо, потому что вы можете просто создать сценарий создания таблицы с помощью встроенного скрипта. Но только для изучения разума вы можете разобрать свой XML и построить Dynamic-SQL.

DECLARE @x XML = 
N'<root number="testdb"> 
    <TABLE_CATALOG>testdb</TABLE_CATALOG> 
    <TABLE_SCHEMA>dbo</TABLE_SCHEMA> 
    <TABLE_NAME>tb_Population</TABLE_NAME> 

    <COLUMN_NAME>ID</COLUMN_NAME> 
    <ORDINAL_POSITION>1</ORDINAL_POSITION> 
    <IS_NULLABLE>YES</IS_NULLABLE> 
    <DATA_TYPE>varchar</DATA_TYPE> 
    <CHARACTER_MAXIMUM_LENGTH>6</CHARACTER_MAXIMUM_LENGTH> 
    <CHARACTER_OCTET_LENGTH>6</CHARACTER_OCTET_LENGTH> 
    <CHARACTER_SET_NAME>iso_1</CHARACTER_SET_NAME> 
    <COLLATION_NAME>SQL_Latin1_General_CP1_CS_AS</COLLATION_NAME> 
</root>'; 

DECLARE @database SYSNAME, 
     @schema SYSNAME, 
     @table SYSNAME, 
     @column_name SYSNAME, 
     @column_position VARCHAR(100), 
     @is_nullable VARCHAR(10), 
     @data_type VARCHAR(100), 
     @character_maximum VARCHAR(100), 
     @collation_name VARCHAR(100); 


SELECT 
@database = t.c.value('TABLE_CATALOG[1]', 'SYSNAME'), 
@schema = t.c.value('TABLE_SCHEMA[1]', 'SYSNAME'), 
@table = t.c.value('TABLE_NAME[1]', 'SYSNAME'), 
@column_name = t.c.value('COLUMN_NAME[1]', 'VARCHAR(100)'), 
@column_position = t.c.value('TABLE_NAME[1]', 'VARCHAR(100)'), 
@is_nullable = t.c.value('IS_NULLABLE[1]', 'VARCHAR(100)'), 
@data_type = t.c.value('DATA_TYPE[1]', 'VARCHAR(100)'), 
@character_maximum = t.c.value('CHARACTER_MAXIMUM_LENGTH[1]', 'VARCHAR(100)'), 
@collation_name = t.c.value('COLLATION_NAME[1]', 'VARCHAR(100)') 
FROM @x.nodes('/root') AS t(c); 

DECLARE @sql NVARCHAR(MAX) = 
N' CREATE TABLE @[email protected]@table(
     @column_name @[email protected]_maximum @is_nullable @collation_name 
);'; 

SET @sql = REPLACE(@sql, '@database', QUOTENAME(@database)); 
SET @sql = REPLACE(@sql, '@schema', QUOTENAME(@schema)); 
SET @sql = REPLACE(@sql, '@table', QUOTENAME(@table)); 
SET @sql = REPLACE(@sql, '@column_name', QUOTENAME(@column_name)); 
SET @sql = REPLACE(@sql, '@data_type', QUOTENAME(@data_type)); 
SET @sql = REPLACE(@sql, '@character_maximum', 
          CASE WHEN @character_maximum IS NULL THEN '' 
          ELSE CONCAT('(', @character_maximum, ')') 
          END); 
SET @sql = REPLACE(@sql, '@is_nullable', 
          CASE WHEN @is_nullable = 'YES' THEN 'NULL' 
          ELSE 'NOT NULL' 
          END); 

SET @sql = REPLACE(@sql, '@collation_name', 
          CASE WHEN @collation_name IS NULL THEN '' 
          ELSE CONCAT('COLLATE ', @collation_name) 
          END); 
PRINT @sql; 

--EXEC [dbo].[sp_executesql] 
--  @sql; 

LiveDemo

Выход:

CREATE TABLE [testdb].[dbo].[tb_Population](
     [ID] [varchar](6) NULL COLLATE SQL_Latin1_General_CP1_CS_AS 
); 

Предупреждение:

Это не производство кода, вы не должны полагаться на него. Только для демонстрационных целей.

Когда вы идете так что вам нужно:

  • ручки угловых случаи
  • проверка много вещей, ваш XML не обеспечивает (PRIMARY/FOREIGN KEY, ограничение, значения по умолчанию)
  • вы подвержены SQL Injection атаки если вы не проверяете каждый параметр
  • , вам нужно пройти через все столбцы, для демонстрации я предположил, что у вас есть только один
  • код изменения условного кода в зависимости от типа
  • изменение структуры XML для обработки нескольких столбцов
  • все больше и больше

Эта задача возможно, но делает это с SQL тратит впустую время, особенно, когда вы можете просто нажмите GENERATE SCRIPT.

+1

Спасибо за информацию и демонстрацию. Это скорее вопрос любопытства на моем конце. Я просто попадаю в xml-сторону вещей и просто задавался вопросом, возможно ли это. Еще раз спасибо! –

Смежные вопросы