вторник, 13 марта 2012 г.

Transfer data an schema using SMO, but without "Transfer" class. More faster method I hope. Using Scripter Using Scripter instead.

Ну вот и получилось решение вопроса Transfer - а. При котором вам не потребуется наличие Integration Services установленного на вашем ПК. Что хотелось бы особо отметить в сравнении с предыдущим примером (Использование Transfer класса) данный способ работает в два раза быстрее. Хотя данные показатели могут разниться и утверждать, что "Wow" это просто чумовой прирост скорости трансфера данных, но таких громких заявлений делать не буду. Хотелось бы конечно по поводу скорости получить ваши комментарии. Так вот сам способ (количество таблиц оставляем тоже и задача ставится такая же).

private void TransferSchemaAndData()
{

         DataTable dataTable = db.EnumObjects(DatabaseObjectTypes.Table);
        List<Microsoft.SqlServer.Management.Sdk.Sfc.Urn> listSchema = new List<Microsoft.SqlServer.Management.Sdk.Sfc.Urn>();
        List<Microsoft.SqlServer.Management.Sdk.Sfc.Urn> listData = new List<Microsoft.SqlServer.Management.Sdk.Sfc.Urn>();

         FillLists (listSchema, listData, dataTable);      

        string PathToFile = Path.GetTempPath() + "\\SomeTransferPackageName.sql";
        Scripter scripter = new Scripter();
        SettingUpScripter(ref scripter, srv, PathToFile);
     
        Microsoft.SqlServer.Management.Sdk.Sfc.Urn[] urr = listSchema.ToArray();
        scripter.Script(urr);

        StreamReader rd = new StreamReader(PathToFile);
        string script = rd.ReadToEnd();

        Database toDb = srv.Databases[toDbName];
        DropTransferedTables(toDb);

        toDb.ExecuteNonQuery(script);
        rd.Close();
        listSchema.Clear();

        scripter.Options.ScriptSchema = false;
        scripter.Options.ScriptData = true;              
     
        urr = listData.ToArray();
        scripter.EnumScript(urr);      

         rd = new StreamReader(PathToFile);
         script = rd.ReadToEnd();

         ClearData(toDb);

         toDb.ExecuteNonQuery(script);
         rd.Close();
         listData.Clear();

         if (File.Exists(PathToFile))
         {
           File.Delete(PathToFile);
         }      
}

private void  FillLists(List<Microsoft.SqlServer.Management.Sdk.Sfc.Urn> listSchema, List<Microsoft.SqlServer.Management.Sdk.Sfc.Urn> listData, DataTable dataTable)
{
   foreach (System.Data.DataRow row in dataTable.Rows)
      {
        string tbName = row["Name"].ToString();
        if (IsDataTableThatWeNeed(tbName))
        {
          listData.Add(new Microsoft.SqlServer.Management.Sdk.Sfc.Urn(row["Urn"].ToString()));
        }
        else if (IsSchemaTableThatWeNeed(tbName))
        {
          listSchema.Add(new Microsoft.SqlServer.Management.Sdk.Sfc.Urn(row["Urn"].ToString()));
        }
      }
}



private void SettingUpScripter(ref Scripter scripter, Server srv, string PathToFile)
    {
      scripter.Server = srv;
      scripter.Options.IncludeHeaders = true;
      scripter.Options.SchemaQualify = true;
      scripter.Options.SchemaQualifyForeignKeysReferences = true;
      scripter.Options.NoCollation = true;
      scripter.Options.DriAllConstraints = true;
      scripter.Options.DriAll = true;
      scripter.Options.DriAllKeys = true;
      scripter.Options.DriIndexes = true;
      scripter.Options.ClusteredIndexes = true;
      scripter.Options.NonClusteredIndexes = true;
      scripter.Options.ToFileOnly = true;
      scripter.Options.ScriptData = false;
      scripter.Options.ScriptSchema = true;
      scripter.Options.FileName = PathToFile;
    }


Пока код не оптимизировался , так сказать первый набросок. В следующем посте расскажу по поводу некоторых функций который здесь использовались а так же опишу возникающие затруднения. В частности почему именно Microsoft.SqlServer.Management.Sdk.Sfc.Urn. А не просто Urn.

3 комментария:

  1. Хорошо! было бы здорово сделать трансфер без использования SMO. Можешь примерчик набросать?

    ОтветитьУдалить
  2. Ну в принципе хорошая просьба, чтоб так сказать осветить тему со всех сторон. В следующем посте выложу что получилось.

    ОтветитьУдалить
  3. получила ли данная тема продолжение? можно без Transfer-а сделать полную копию базы?

    ОтветитьУдалить