Example #1
0
        public List <TableItem> GetTableList()
        {
            var tables      = new List <TableItem>();
            var key_columns = GetPrimaryKeyColumn();
            var id_columns  = GetIdentityColumns();

            var rows = this.RunQuery(@"
SELECT
    t.Name AS TABLE_NAME,
    s.NAME AS TABLE_SCHEMA,
    p.rows AS RowCounts
FROM
    sys.tables t
INNER JOIN
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
LEFT OUTER JOIN
    sys.schemas s ON t.schema_id = s.schema_id
WHERE
    t.NAME NOT LIKE 'dt%'
    AND t.is_ms_shipped = 0
    AND i.OBJECT_ID > 255
    AND p.rows > 0
GROUP BY
    t.Name, s.Name, p.Rows
ORDER BY RowCounts DESC");

            foreach (var row in rows)
            {
                var name  = "[" + row["TABLE_SCHEMA"] + "].[" + row["TABLE_NAME"] + "]";
                var count = Convert.ToInt32(row["RowCounts"]);

                TableItem item = new TableItem {
                    name  = name,
                    count = count
                };

                if (id_columns.ContainsKey(name))
                {
                    item.id_column = id_columns[name];
                }

                if (key_columns.ContainsKey(name))
                {
                    item.pkey_column = key_columns[name];
                }

                tables.Add(item);
            }

            return(tables);
        }
Example #2
0
        public void CopyData(TableItem item, int count)
        {
            SqlConnection conn1 = new SqlConnection(this.fromConnString);

            conn1.Open();

            SqlConnection conn2 = new SqlConnection(this.toConnString);

            conn2.Open();

            bool has_error = false;

            int offset = 0, perpage = 1000, total = 0, duplicates = 0;

            while (!has_error && total < count)
            {
                SqlCommand cmd1 = conn1.CreateCommand();
                cmd1.CommandText = String.Format(
                    "SELECT * FROM {0} ORDER BY {1} DESC OFFSET {2} ROWS FETCH NEXT {3} ROWS ONLY",
                    item.name, item.sort_column,
                    offset, perpage);

                // 避免打印太多进度
                if (offset % 100000 == 0)
                {
                    Console.WriteLine("offset=" + offset + "; duplicates=" + duplicates);
                }

                // 连续 10K 重复内容,直接退出
                if (duplicates >= 10000)
                {
                    Console.WriteLine("Too many duplicates, finishing table early");
                    break;
                }

                SqlDataReader reader = cmd1.ExecuteReader();
                if (!reader.HasRows)
                {
                    Console.WriteLine("No more rows in " + item.name + ", total read " + offset);
                    break;
                }

                while (reader.Read())
                {
                    List <string> columns1 = new List <string>(), columns2 = new List <string>();
                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        columns1.Add("[" + reader.GetName(i) + "]");
                        columns2.Add("@" + reader.GetName(i));
                    }

                    try
                    {
                        SqlCommand cmd2 = conn2.CreateCommand();
                        cmd2.CommandText = String.Format(
                            "INSERT INTO {0} ({1}) VALUES ({2})",
                            item.name,
                            String.Join(", ", columns1.ToArray()),
                            String.Join(", ", columns2.ToArray())
                            );

                        if (item.id_column != null)
                        {
                            cmd2.CommandText =
                                "SET IDENTITY_INSERT " + item.name + " ON; " +
                                cmd2.CommandText +
                                "SET IDENTITY_INSERT " + item.name + " OFF; ";
                        }

                        for (int i = 0; i < columns2.Count; i++)
                        {
                            cmd2.Parameters.AddWithValue(columns2[i], reader.GetValue(i));
                        }

                        cmd2.ExecuteNonQuery();
                        duplicates = 0;
                    }
                    catch (SqlException se)
                    {
                        // duplicated key
                        if (se.Number == 2627)
                        {
                            duplicates++;
                            continue;
                        }

                        Console.WriteLine(se);
                        has_error = true;
                        break;
                    }

                    ++total;
                }
                reader.Close();

                offset += perpage;
            }

            Console.WriteLine("Copied " + total + " rows in total, duplicates " + duplicates);
        }