繁体   English   中英

将SQL Server 2008数据库架构克隆到新数据库-以编程方式(PHP?)

[英]Cloning an SQL Server 2008 Database Schema to a new Database - Programatically (PHP?)

我已经在Google上进行了一些Google搜索和搜索,但是在此问题上我找不到很多帮助。 我正在设计一个利用Microsoft SQL Server 2008 Server的Web服务。 相关的结构是这样的……有一个主数据库,其中存储了所有主帐户/公司信息(公司名称,地址等)。 此外,每个帐户/公司都有数据库,其中包含该帐户的所有相关(元)数据(用户,设置等)。

SQL2008 Server
|---MainDatabase
|-------Accounts Table
|-----------Account Record where ID = 1
|-----------Account Record where ID = 2
|-----------Account Record where ID = 3
|---AccountDatabase00001
|-------Users Table for account where ID = 1
|---AccountDatabase00001
|-------Users Table for account where ID = 2

创建新帐户时(例如,ID = 3),我试图找出一种方法将AccountDatabase0001的表模式和视图(不包含数据)克隆到名为AccountDatabase00003的新数据库中。 只要可以从PHP页面以某种方式调用复制,我几乎可以使用任何语言来执行复制。

是否有人遇到过这样的PHP脚本或与此相关的其他任何语言的脚本? 是否可以发送命令SQL Server为我执行此命令? 我确定可以通过手动遍历结构并编写SQL语句来创建每个对象找到自己的方式,但是我希望可以找到更简单的方法。

您可以使用SMO做到这一点,而不会带来太多麻烦。 这是一个提供特定代码的站点。 该代码在C#中,但是希望您可以将其集成或转换为PHP。

我找到了一种远程简单的方法,可以在PHP中通过自定义编写的存储过程提供一些帮助,而该过程只需要存在于您希望克隆的数据库中(对我而言,它始终是AccountDatabase_1 )。 您将表名传递给存储过程,它返回创建它需要运行的脚本(我们将在第二个数据库上执行此操作)。 对于视图,创建脚本实际上存储在Information_Schema.Views表中,因此您只需从中拉出视图名称和创建代码即可轻松创建克隆。

存储PROC GenerateScript()

USE [SOURCE_DATABASE_NAME]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[GenerateScript] 
(            
    @tableName varchar(100)
)            
as            
If exists (Select * from Information_Schema.COLUMNS where Table_Name= @tableName)            
Begin            
    declare @sql varchar(8000)            
    declare @table varchar(100)            
    declare @cols table (datatype varchar(50))          
    insert into @cols values('bit')          
    insert into @cols values('binary')          
    insert into @cols values('bigint')          
    insert into @cols values('int')          
    insert into @cols values('float')          
    insert into @cols values('datetime')          
    insert into @cols values('text')          
    insert into @cols values('image')          
    insert into @cols values('uniqueidentifier')          
    insert into @cols values('smalldatetime')          
    insert into @cols values('tinyint')          
    insert into @cols values('smallint')          
    insert into @cols values('sql_variant')          

    set @sql='' 

    Select 
        @sql=@sql+             
        case when charindex('(',@sql,1)<=0 then '(' else '' end +Column_Name + ' ' +Data_Type + 
        case when Column_name='id' then ' IDENTITY ' else '' end +            
        case when Data_Type in (Select datatype from @cols) then '' else  '(' end+
        case when data_type in ('real','money','decimal','numeric')  then cast(isnull(numeric_precision,'') as varchar)+','+
        case when data_type in ('real','money','decimal','numeric') then cast(isnull(Numeric_Scale,'') as varchar) end
        when data_type in ('char','nvarchar','nchar') then cast(isnull(Character_Maximum_Length,'') as varchar) else '' end+
        case when data_type ='varchar' and Character_Maximum_Length<0 then 'max' else '' end+
        case when data_type ='varchar' and Character_Maximum_Length>=0 then cast(isnull(Character_Maximum_Length,'') as varchar) else '' end+
        case when Data_Type in (Select datatype from @cols)then '' else  ')' end+
        case when Is_Nullable='No ' then ' Not null ' else ' null ' end + 
        case when Column_Default is not null then 'DEFAULT ' + Column_Default else '' end + ','
    from 
        Information_Schema.COLUMNS where Table_Name=@tableName            

    select  
        @table=  'Create table ' + table_Name 
    from 
        Information_Schema.COLUMNS 
    where 
        table_Name=@tableName            

    select @sql=@table + substring(@sql,1,len(@sql)-1) +' )'            

    select @sql  as DDL         

End            

Else        
    Select 'The table '+@tableName + ' does not exist'           

的PHP

function cloneAccountDatabase($new_id){

    $srcDatabaseName = "AccountDatabase_1"; //The Database we are cloning
    $sourceConn = openDB($srcDatabaseName);

    $destDatabaseName = "AccountDatabase_".(int)$new_id;
    $destConn = openDB($destDatabaseName);

    //ENSURE DATABASE EXISTS, OR CREATE IT      
    if ($destConn==null){
        odbc_exec($sourceConn, "CREATE database " . $destDatabaseName);
        $destConn = openDB($destDatabaseName);
    }

    //BUILD ARRAY OF TABLE NAMES
    $tables = array();
    $q = odbc_exec($sourceConn, "SELECT name FROM sys.Tables");
    while (odbc_fetch_row($q))
        $tables[]=odbc_result($q,"name");


    //CREATE TABLES
    foreach ($tables as $tableName){
        $q=odbc_exec($sourceConn, "exec GenerateScript '$tableName';");
        odbc_fetch_row($q);
        $sql = odbc_result($q, 'ddl');
        $q=odbc_exec($destConn, $sql);
    }

    //BUILD ARRAY OF VIEW NAMES AND CREATE
    $q = odbc_exec($sourceConn, "SELECT * FROM Information_Schema.Views");
    while (odbc_fetch_row($q)){
        $view=odbc_result($q,"table_name");
        $sql = odbc_result($q, "view_definition");
        odbc_exec($destConn, $sql);
    }           

    return(true);   
}

更新

CLONEDATABASE函数在较新版本的MSSQL中可用。

https://docs.microsoft.com/zh-cn/sql/t-sql/database-console-commands/dbcc-clonedatabase-transact-sql?view=sql-server-2017

//Clone AccountDatabase_1 to a database called AccountDatabase_2

DBCC CLONEDATABASE (AccountDatabase_1, AccountDatabase_2) WITH VERIFY_CLONEDB, NO_STATISTICS;
ALTER DATABASE AccountDatabase_2 SET READ_WRITE WITH NO_WAIT;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM