【问题标题】:Update all tables schema from another database从另一个数据库更新所有表架构
【发布时间】:2020-02-29 07:22:48
【问题描述】:

我有两个数据库 - 我的旧数据库为 DB1,我的新数据库和编辑后的数据库为 DB2

我需要一个查询来搜索 DB2 中的所有表并找到新的内容,然后根据 DB2 更新 DB1 中的列模式。

如何使用查询(不是 Management Studio)来做到这一点?

我对此一无所知。

【问题讨论】:

  • 我建议您为此任务使用 SQL Server Data Tools (SSDT) 架构比较。 SSDT 是 Visual Studio 2019 的一项功能,架构比较可以从 Tools-->SQL Server 菜单启动。社区版是免费的,可以here下载。
  • @DanGuzman 谢谢,但我需要在最终用户的机器上进行这项工作并更新旧项目结构!
  • 最终用户是如何获得 DB1 和 DB2 的?我假设这些数据库是由您提供的,希望是从源代码控制的数据库代码生成的。使用 SSDT,您可以在您的机器上生成部署脚本并在最终用户的机器上执行以升级数据库。或者,您可以在用户计算机上运行 SSDT SQLPACKAGE 工具作为安装程序的一部分。
  • @DanGuzman 我的问题:例如,每个客户端可能都有一个版本(1 或 2 或 3 或 ...),现在我们想将所有版本都转换为版本 4!版本 1 有 1 列,版本 2 有 2 列,等等 .. 现在版本 4 有 4 列。我们必须在版本 1 中添加 3 列,在版本 2 中添加两列......
  • 分发所需的状态 V4 模型并使用 SQLPACKAGE 升级客户端。您仍应测试每个升级路径。

标签: sql-server tsql database-schema


【解决方案1】:

我试图通过这个步骤来解决这个问题,我希望这个答案对你有所帮助。 1- 通过此过程捕获 DB2 中的所有列。

USE [LastDatabase]
GO

/****** Object:  StoredProcedure [dbo].[CaptureMyColumns]    Script Date: 01/10/2022 05:33:09 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


create proc [dbo].[CaptureMyColumns]
as
IF OBJECT_ID(N'dbo.LastColumns', N'U') IS NOT NULL  
begin 
   DROP TABLE [dbo].[LastColumns];  
 SELECT    ROW_NUMBER() OVER (
    ORDER BY T.name
   ) id, T.name AS Table_Name ,
       C.name AS Column_Name ,
       P.name AS Data_Type ,
      c.collation_name ,
     p.is_nullable ,
c.max_length,object_definition(c.default_object_id)[defaultValue],c.is_identity 
into newcolumns
FROM   sys.objects AS T
       JOIN sys.columns AS C ON T.object_id = C.object_id
       JOIN sys.types AS P ON C.system_type_id = P.system_type_id
WHERE  T.type_desc = 'USER_TABLE' and p.name <> 'sysname'
end
else 
begin 
 SELECT    ROW_NUMBER() OVER (
    ORDER BY T.name
   ) id, T.name AS Table_Name ,
       C.name AS Column_Name ,
       P.name AS Data_Type ,
      c.collation_name ,## Heading ##
     p.is_nullable ,
c.max_length,object_definition(c.default_object_id)[defaultValue],c.is_identity 
FROM   sys.objects AS T
       JOIN sys.columns AS*strong text* C ON T.object_id = C.object_id
       JOIN sys.types AS P ON C.system_type_id = P.system_type_id
WHERE  T.type_desc = 'USER_TABLE' and p.name <> 'sysname'
end 


GO

2- 仅生成脚本 从 DB2 [新数据库] 检查此表 [LastColumns](架构和数据)并在 DB1(旧数据库)中执行此脚本 根据您的数据库 [最后一个数据库],脚本将是这样的

CREATE TABLE [dbo].[Lastcolumns](
[id] [bigint] NULL,
[Table_Name] [sysname] NOT NULL,
[Column_Name] [sysname] NULL,
[Data_Type] [sysname] NOT NULL,
[collation_name] [sysname] NULL,
[is_nullable] [bit] NULL,
[max_length] [smallint] NOT NULL,
[defaultValue] [nvarchar](max) NULL,
[is_identity] [bit] NOT NULL

) 开启 [主要] 去吧

插入 [dbo].[newcolumns]([id]、[Table_Name]、[Column_Name]、[Data_Type]、[collat​​ion_name]、[is_nullable]、[max_length]、[defaultValue]、[is_identity])值( 1, N'accounts', N'id', N'int', NULL, 1, 4, NULL, 1)

3 - 在数据库中升级

右键单击您上次更新的数据库并生成脚本:

不要忘记如果不存在选项:

3 - 现在,如果此脚本在旧数据库中找不到列,您可以添加列

DECLARE @Counter INT 
SET @Counter=1
DECLARE @Counter2 INT 
SET @Counter2=1
DECLARE @tbCount INT=(select COUNT(0) from newColumns )
WHILE ( @Counter <= @tbCount)
BEGIN
declare @tb_name nvarchar(50)=(select table_name from newColumns where id=@counter);
declare @col_name nvarchar(50)=(select column_name from newColumns where id=@counter);
declare @col_typ nvarchar(50)=(select 
case when data_type='nvarchar' then 'nvarchar('+convert(nvarchar(50),max_length)+')'
 when data_type='char' then 'char('+convert(nvarchar(50),max_length)+')'
else data_type end [ee]

 from newColumns where id=@counter);
 
declare @nu nvarchar(50)=(select case when is_nullable='False' then 'not null default ' else 'null' end [es] from newColumns where id=@counter);
declare @defaultValue nvarchar(50)=(select defaultValue from newColumns where id=@counter);

IF not EXISTS (
  SELECT * 
  FROM   sys.columns 
  WHERE  object_id = OBJECT_ID(N'[dbo].['+@tb_name+']') 
         AND name = @col_name
)
BEGIN
exec ( 'ALTER TABLE '+@tb_name+' ADD '+@col_name+' '+
 @col_typ +' '+ @nu +' '+ @defaultValue +';')
print ( 'ALTER TABLE '+@tb_name+' ADD '+@col_name+' '+
 @col_typ +' '+ @nu +' '+ @defaultValue +';') 
 
  SET @Counter2  = @Counter2  + 1 
END


    SET @Counter  = @Counter  + 1
END
   print  'End Of Loop'
  

4 - 最后通过从 Last DB 生成脚本并在旧 DB 中执行来删除和创建所有视图和函数

检查除表格之外的所有内容:

删除并创建:

======================== 这可能不是完美的方法,但它通常可以有效地帮助我

谢谢,

【讨论】:

    猜你喜欢
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多