SQL – Gerando Inserts de Tabelas via T-SQL

Postado em 11/02/2009 17:02:47 por Tomás Vásquez

Mais uma da série: me aventurando no SQL Server.

Apesar do SQL Management Studio Express ser uma ferramenta poderosa e gratuita, peca em algumas funcionalidades simples que a maioria das ferramentas free tem. A título de exemplo, as ferramentas do MySQL como o Administrator e o Query Browser são extremente completas, auxiliando inclusive em uma funcionalidade que coloque em questão aqui. A geração de scripts de dados de um banco.

Tá, conseguimos facilmente geraro script de criação das tabelas, procs, enfim, tudo mais de objetos existentes no banco através SQL Management Studio Express, clicando com o botão direto do mouse sobre o database na janela Object Explorer, indo em Tasks, Generate Scripts… Daí, basta selecionar os objetos a serem gerados e voilá! Está tudo aí, pronto para ser salvo e criado em qualquer outra servidor.

sqlmanagementstudioexpressgeneratescripts

Gerando Scripts do SQL Management Studio

O problema são os dados. Tudo bem, dá até pra fazer um backup em arquivo binário, mas e se o servidor for de acesso restrito? A rotina de backup só funciona apontando para os discos existentes no computador instalado. Com algum esforço, daria para apontar para um diretório da rede, mas nem sempre isso está acessível.

Portanto, para auxiliar nesta tarefa, o colega Mark Clerget publicou um seu blog uma query muito bacana que é capaz de gerar os inserts dos dados das tabelas de um determinado banco. Dê uma olhada no script abaixo:


create table #tmp (
SQLText varchar(8000) )

create table #tmp2 (
Id int identity,
SQLText varchar(8000) )

set nocount on

delete #tmp
delete #tmp2

declare @vsSQL varchar(8000),
@vsCols varchar(8000),
@vsTableName varchar(40)

declare csrTables cursor for
select name
from sysobjects
where type in ('u')
and name in ('Customers')
order by name

open csrTables
fetch next from csrTables into @vsTableName

while (@@fetch_status = 0)
begin

select @vsSQL = '',
@vsCols = ''
select @vsSQL = @vsSQL +
CASE when sc.type in (39,47,61,111) then
'''''''''+' + 'isnull(rtrim(replace('+ sc.name + ','''''''','''''''''''')),'''')' + '+'''''',''+'
when sc.type = 35 then
'''''''''+' + 'isnull(rtrim(replace(substring('+ sc.name + ',1,1000),'''''''','''''''''''')),'''')' + '+'''''',''+'
else
'isnull(convert(varchar,' + sc.name + '),''null'')+'',''+'
end
from syscolumns sc
where sc.id = object_id(@vsTableName)
order by ColID

select @vsCols = @vsCols + sc.name + ','
from syscolumns sc
where sc.id = object_id(@vsTableName)
order by ColID

select @vsSQL = substring(@vsSQL,1,datalength(@vsSQL)-1)

select @vsCols = substring(@vsCols,1,datalength(@vsCols)-1)

insert #tmp
exec ('select ' + @vsSQL + ' from ' + @vsTableName)

update #tmp
set sqltext = 'insert ' + @vsTableName + '(' + @vsCols + ') values(' + substring(sqltext,1,datalength(sqltext)-1) + ')'

insert #tmp2
select 'DELETE from ' + @vsTableName

insert #tmp2 values ('GO')

if (select count(id) from syscolumns where id = object_id(@vsTableName) and ((status & 128) = 128) ) = 1
begin
insert #tmp2
select 'set identity_insert ' + @vsTableName + ' on'
end

insert #tmp2
select * from #tmp

if (select count(id) from syscolumns where id = object_id(@vsTableName) and ((status & 128) = 128) ) = 1
begin
insert #tmp2
select 'set identity_insert ' + @vsTableName + ' off'
end

insert #tmp2 values ('GO')

insert #tmp2
select 'update statistics ' + @vsTableName

insert #tmp2 values ('GO')

delete #tmp

fetch next from csrTables into @vsTableName

end

close csrTables
deallocate csrTables

update #tmp2
set sqltext = substring(sqltext,1,charindex(',)',sqltext)-1) + ',NULL)'
where not(charindex(',)',sqltext) = 0)

update #tmp2
set sqltext = replace(sqltext, ',''''',',null')
where not (charindex(',''''',sqltext) = 0)

update #tmp2
set sqltext = replace(sqltext, '(''''',',null')
where not (charindex('(''''',sqltext) = 0)

set nocount off

select sqltext from #tmp2 order by id

go

drop table #tmp
drop table #tmp2

Destaquei propositalmente a linha com o código “and name in ('Customers')” pois é este que faz o filtro nas tabelas contidas em sysobjects.. Se quiser apenas um subconjunto das tabelas nas quais terão o script gerado, basta alterar este filtro. O resultado da query acima executada sobre o banco de dados Northwind na tabela Region, pode ser visto na figura abaixo:

Script Gerado

Script Gerado

É um belo macete para as horas de aperto. Porém, este script não é infalível. Para alguns tipos de campos, como o image, ainda são gerados alguns erros. Mas como eles são excessão, é possível tratá-los de maneira separada. Caso alguém tenha alguma sugestão de melhoria, é avisar!

Abraços

Tomás

  1. 2 comentários para “SQL – Gerando Inserts de Tabelas via T-SQL”

  2. Por leonardo em 23/05/2009 15:05:10 | Responder

    excelente artigo, estava pensando em fazer uma rotina dessa, derrepente encontro uma pronta.

  3. muito bom o artigo!
    parabéns

Você precisa ser um usuário registrado para inserir um comentário. Faça seu login clicando aqui