0

I'm working on a C# application to generate the script. I have the following settings below, but tables/insert statements are being generated for other schemas. I just want one specific schema and all the schema/data from it.

I tried to set options.WithDependencies = false;, but then it wouldn't give me everything I needed as in scripting the data.

What other setting am I missing?

        private void GeneratingMainSQLScript(string schema)
        {
            Server srv = new Server(@".\sql2017");
            Database dbs = srv.Databases["SOURCE_T"];
            ScriptingOptions options = new ScriptingOptions();
            options.TargetServerVersion = SqlServerVersion.Version140;
            options.EnforceScriptingOptions = true;
            options.ScriptData = true;
            options.ScriptDrops = false;
            options.FileName = GenerateScriptFileName(schema, false);
            options.EnforceScriptingOptions = true;
            options.ScriptSchema = true;
            options.IncludeHeaders = true;
            options.AppendToFile = true;
            options.Indexes = true;
            options.WithDependencies = true;

            var tableNames = GetTableNames(schema);

            int progressCounter = 1;
            foreach (var tbl in tableNames)
            {
                if (tbl.SchemaName == "dbo" && tbl.TableName == "FileDatas")
                {
                    options.ScriptData = false;
                }

                dbs.Tables[tbl.TableName, tbl.SchemaName].EnumScript(options);

                DisplayDebug(string.Format("Running migration schema's ({2}) main genreated script | Total: {0} | Processing #: {1}", tableNames.Count, progressCounter, schema));

                progressCounter++;
            }
        }

UPDATE:

I made these changes after working with my lead and we are close. The issue now: it is generating the FKS after creating the table and not at the END of the file like when you do it via SSMS directly?

Server srv = new Server(@".\sql2017");
            Database dbs = srv.Databases["SOURCE_T"];
            ScriptingOptions options = new ScriptingOptions();
            options.FileName = GenerateScriptFileName(schema, isSchemaOnly);
            options.EnforceScriptingOptions = true;
      
            // start
            options.AnsiPadding = false;
            options.AppendToFile = true;
            options.ContinueScriptingOnError = false;
            options.ConvertUserDefinedDataTypesToBaseType = false;
            options.WithDependencies = false;
            options.IncludeHeaders = true;
            options.IncludeScriptingParametersHeader = false;
            options.SchemaQualify = true;
            options.Bindings = false;
            options.NoCollation = true;
            options.Default = true;
            options.ScriptDrops = false;
            options.ScriptSchema = isSchemaOnly;
            options.ExtendedProperties = true;
            options.TargetServerVersion = SqlServerVersion.Version140;
            options.TargetDatabaseEngineType = Microsoft.SqlServer.Management.Common.DatabaseEngineType.Standalone;
            options.LoginSid = false;
            options.Statistics = false;
            options.ScriptData = !isSchemaOnly;
            options.ChangeTracking = false;
            options.DriAllConstraints = true;
            options.ScriptDataCompression = false;
            options.DriForeignKeys = true;
            options.FullTextIndexes = false;
            options.Indexes = false;
            options.DriPrimaryKey = true;
            options.Triggers = false;
            options.DriUniqueKeys = true;
            options.DriAll = true;

ttaylor27272727
  • 195
  • 3
  • 18
  • Put `EnumScript` inside the `if`? Or bail out the `foreach` with `continue;`? – Charlieface Feb 17 '21 at 00:26
  • @Charlieface: Well, it is like within `EnumScript` that if it has a FK to a specific table, it is generating the dependencies, and then if that table is used again with a FK, it will generate it again. – ttaylor27272727 Feb 17 '21 at 00:39
  • Does this answer your question? [How to set SMO ScriptingOptions to guarantee exact copy of table?](https://stackoverflow.com/questions/11658143/how-to-set-smo-scriptingoptions-to-guarantee-exact-copy-of-table) Looks like you need `DriAll = true` and `WithDependencies = false` – Charlieface Feb 17 '21 at 00:59
  • @Charlieface: Ugg, now not all the scripted data for the inserts is not there! It isn't generating the duplicate data anymore though. – ttaylor27272727 Feb 17 '21 at 01:22
  • @Charlieface: I updated the ticket and we are close! I added an UPDATE, can you take a look to see maybe what options I am missing that will generate the FKS at the end of the script instead of after each table? – ttaylor27272727 Feb 17 '21 at 15:38
  • Well you could turn **off** DriAll, then get those scripted separately – Charlieface Feb 17 '21 at 16:04
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/228857/discussion-between-ttaylor27272727-and-charlieface). – ttaylor27272727 Feb 17 '21 at 16:33
  • @Charlieface: I think I have a resolution. I'll post it when I fully test it and validate it is working as expected. Thanks a lot for your insight into this issue! – ttaylor27272727 Feb 17 '21 at 19:28

1 Answers1

0

Here is the solution I am using. The key here is all the options that I have set, but also how I pull the table names. GetTablesNames will obtain the tables in the order that they need to be made in, which allows for everything to process properly along with the FKs.

  1. Obtaining the tables properly
  2. setting this variable to false: options.WithDependencies = false;

Are the keys to my solution.

        private void GeneratingMainSQLScript(string schema, bool isSchemaOnly)
        {
            Server srv = new Server(sqlServer);
            Database dbs = srv.Databases["SOURCE_T"];
            ScriptingOptions options = new ScriptingOptions();
            options.FileName = GenerateScriptFileName(schema, isSchemaOnly);
            options.EnforceScriptingOptions = true;

            // start
            options.AnsiPadding = false;
            options.AppendToFile = true;
            options.ContinueScriptingOnError = false;
            options.ConvertUserDefinedDataTypesToBaseType = false;
            options.WithDependencies = false;
            options.IncludeHeaders = true;
            options.IncludeScriptingParametersHeader = false;
            options.SchemaQualify = true;
            options.Bindings = false;
            options.NoCollation = true;
            options.Default = true;
            options.ScriptDrops = false;
            options.ScriptSchema = true;
            options.ExtendedProperties = true;
            options.TargetServerVersion = SqlServerVersion.Version140;
            options.TargetDatabaseEngineType = Microsoft.SqlServer.Management.Common.DatabaseEngineType.Standalone;
            options.LoginSid = false;
            options.Statistics = false;
            options.ScriptData = true;
            options.ChangeTracking = false;
            options.DriAllConstraints = true;
            options.ScriptDataCompression = false;
            options.DriForeignKeys = true;
            options.FullTextIndexes = false;
            options.Indexes = false;
            options.DriPrimaryKey = true;
            options.Triggers = false;
            options.DriUniqueKeys = true;


            if (isSchemaOnly == true)
            {
                options.ScriptSchema = true;
                options.DriForeignKeys = true;
                options.SchemaQualify = true;
                options.SchemaQualifyForeignKeysReferences = true;
                options.DriAll = true;
                options.ScriptData = false;
            }
            else
            {
                options.ScriptSchema = false;
                options.ScriptData = true;
                options.DriAll = false;
            }

            var tableNames = GetTablesNames(schema, sourceDefaultConnection, true);

            int progressCounter = 1;
            foreach (var tbl in tableNames)
            {
                if (tbl.SchemaName == "HR" && tbl.TableName == "FileDatas" && isSchemaOnly == false)
                {
                    continue;
                }
                else
                {
                    dbs.Tables[tbl.TableName, tbl.SchemaName].EnumScript(options);
                }

                DisplayDebug(string.Format("Running migration schema's ({2}) main generated script | Total: {0} | Processing #: {1}", tableNames.Count, progressCounter, schema));

                progressCounter++;
            }
        }

        private IList<DatabaseTableDTO> GetTablesNames(string schema, string connectionName, bool isAscending)
        {
            string sql = string.Format(@"WITH cte (lvl, object_id, name, schema_Name) AS
                                          (SELECT 1, object_id, sys.tables.name, sys.schemas.name as schema_Name
                                           FROM sys.tables Inner Join sys.schemas on sys.tables.schema_id = sys.schemas.schema_id
                                           WHERE type_desc = 'USER_TABLE'
                                             AND is_ms_shipped = 0
                                           UNION ALL SELECT cte.lvl + 1, t.object_id, t.name, S.name as schema_Name
                                           FROM cte
                                           JOIN sys.tables AS t ON EXISTS
                                             (SELECT NULL FROM sys.foreign_keys AS fk
                                              WHERE fk.parent_object_id = t.object_id
                                                AND fk.referenced_object_id = cte.object_id )
                                           JOIN sys.schemas as S on t.schema_id = S.schema_id
                                           AND t.object_id <> cte.object_id
                                           AND cte.lvl < 30
                                           WHERE t.type_desc = 'USER_TABLE'
                                             AND t.is_ms_shipped = 0 )
                                        SELECT schema_Name, name, MAX (lvl) AS dependency_level
                                        FROM cte
                                        where schema_Name = '{0}'
                                        GROUP BY schema_Name, name
                                        ORDER BY dependency_level {1},schema_Name, name;", schema, isAscending == true ? "ASC" : "DESC");

            var connectionString = ConfigurationManager.ConnectionStrings[connectionName];

            var listOfTables = new List<DatabaseTableDTO>();

            using (SqlConnection conn = new SqlConnection(connectionString.ConnectionString))
            {
                conn.Open();
                using (var command = new SqlCommand(sql, conn))
                {
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            listOfTables.Add(new DatabaseTableDTO { SchemaName = schema, TableName = reader.GetString(1) });
                        }
                    }
                }
            }

            return listOfTables;
        }

        public class DatabaseTableDTO
        {
            public string SchemaName { get; set; }

            public string TableName { get; set; }
        }
ttaylor27272727
  • 195
  • 3
  • 18