Visual Studio数据库的数量项目数据从现有数据加载脚本

时间:2015-05-01 14:45:51

标签: sql sql-server tsql visual-studio-2013 sql-server-2012

所以,我一直在寻找一个解决方案,并提出了什么样的工作......但我不能感觉必须有更优雅的东西。

我正在寻找的是能够从填充的数据库中提取现有数据&将该数据合并到加载脚本中。数据库架构&配置数据将多次推出,并随着开发的继续而改变,因此能够从现有数据重建配置数据非常重要,而不是从脚本中保存的静态数据重建。

这是我拼凑的东西:

create procedure #dump (
    @TableName      varchar(128)
    )
as

set nocount on
set rowcount 0

declare @template varchar(max)
set @template = 'SET IDENTITY_INSERT [dbo].[' + @TableName + '] ON

MERGE INTO [dbo].[' + @TableName + '] AS [Target]
USING
(
VALUES
{vals}
)
AS [Source] ({fields})
ON [Target].[{pk}] = [Source].[{pk}]
WHEN MATCHED THEN UPDATE SET
{upds}
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
{fields}
)
VALUES
(
{fields}
);

SET IDENTITY_INSERT [dbo].[' + @TableName + '] OFF
--------------------------------------------------
'

declare @pk varchar(max) = ''
declare @vals varchar(max) = '/*
set concat_null_yields_null off
select ''' + '(' + ''' + replace(replace({casts} + '') ,'', '',,'', '', null,''), ''' + ',)' + ''', ''' + ',null)' + ''') from [' + @TableName + ']
*/'
declare @casts varchar(max) = ''
declare @fields varchar(max) = ''
declare @upds varchar(max) = ''
declare @inserts varchar(max) = ''

set @pk = SUBSTRING(@TableName, 1, len(@TableName) - 1) + 'ID'

declare cur_flds
cursor for select c.name, c.type
from syscolumns c
where c.id = object_id(@TableName)
order by c.colid

declare @fn varchar(max)
declare @ft int

open cur_flds
fetch next from cur_flds into @fn, @ft
while @@FETCH_STATUS = 0
    begin
        if len(@fields) > 0
            set @fields = @fields + ', '
        set @fields = @fields + '[' + @fn + ']'

        if len(@casts) > 0
            set @casts = @casts + ' + ' + ''','' + '
        if @ft in(56,55,50,38,48)
            set @casts = @casts + 'cast([' + @fn + '] as varchar)'
        else if @ft = 111
            set @casts = @casts + ''''''''' + ' + 'cast([' + @fn + '] as varchar) + ' + ''''''''''
        else
            set @casts = @casts + ''''''''' + ' + 'replace([' + @fn + '], ''''''''' + ', ' + ''''''''''''') + '''''''''


        if @fn != @pk
            begin
                if len(@upds) > 0
                    set @upds = @upds + ', '
                set @upds = @upds + '[Target].[' + @fn + '] = [Source].[' + @fn + ']'
            end

        fetch next from cur_flds into @fn, @ft
    end

close cur_flds
deallocate cur_flds

set @vals = REPLACE(@vals, '{casts}', @casts)

set @template = REPLACE(@template, '{pk}', @pk)
set @template = REPLACE(@template, '{vals}', @vals)
set @template = REPLACE(@template, '{fields}', @fields)
set @template = REPLACE(@template, '{upds}', @upds)
set @template = REPLACE(@template, '{inserts}', @inserts)

print @template

go


exec #dump 'ActionItemSystems'

drop proc #dump

最终给出了输出:

SET IDENTITY_INSERT [dbo].[ActionItemSystems] ON

MERGE INTO [dbo].[ActionItemSystems] AS [Target]
USING
(
VALUES
/*
set concat_null_yields_null off
select '(' + replace(replace(cast([ActionItemSystemID] as varchar) + ',' + '''' + replace([ActionItemSystemName], '''', '''''') + '''' + ') ,', ',,', ', null,'), ',)', ',null)') from [ActionItemSystems]
*/
)
AS [Source] ([ActionItemSystemID], [ActionItemSystemName])
ON [Target].[ActionItemSystemID] = [Source].[ActionItemSystemID]
WHEN MATCHED THEN UPDATE SET
[Target].[ActionItemSystemName] = [Source].[ActionItemSystemName]
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
[ActionItemSystemID], [ActionItemSystemName]
)
VALUES
(
[ActionItemSystemID], [ActionItemSystemName]
);

SET IDENTITY_INSERT [dbo].[ActionItemSystems] OFF

从这一点来说,我可以把注释掉的位

set concat_null_yields_null off
select '(' + replace(replace(cast([ActionItemSystemID] as varchar) + ',' + '''' + replace([ActionItemSystemName], '''', '''''') + '''' + ') ,', ',,', ', null,'), ',)', ',null)') from [ActionItemSystems]

执行该操作,并获得如下输出:

(33,'7111-5 -Upstream/Seed Lab') ,
(32,'7301-Seed Lab') ,
(30,'7807 UFDF') ,
(14,'BAS Panel Upgrade') ,
(1,'Clean Steam') ,
(13,'DCS') ,
(2,'HWFI') ,
(3,'MCS') ,
(12,'MES') ,
(31,'Seed Lab') ,
(18,'UCS WRO') ,
(34,'Upstream Seed Lab') ,
(29,'Viral Filtration') ,
然后可以将

合并(不包括最终的逗号)到脚本中。

现在,这个解决方案起作用,但它很脆弱。它取决于各种假设(例如,表名将具有表名的主键 - 尾随'以及加ID),这可能不适用于每个解决方案。它还需要切割和切割。粘贴,并在表结构发生变化时从一开始就重新运行。

这可能是相当多的背景......我部分分享,因为我找不到类似的东西。以为有人可能从中受益。但是,我仍然回到我真正的问题,也就是说:哪里有为VS数据库项目生成这种脚本的工具?确实应该有一些东西 - 考虑到主键是什么,会产生整个事物等等。

1 个答案:

答案 0 :(得分:3)

您可以尝试使用此过程生成MERGE语句: https://github.com/readyroll/generate-sql-merge 它是您已有的更高级版本。