我如何以编程方式从数据库表中“插入”数据脚本文件?

时间:2010-07-12 07:29:14

标签: c# sql-server sql-server-2005

是否有一个优雅的面向对象的框架?

3 个答案:

答案 0 :(得分:2)

这是我编写的一些代码,用于为数据库中的每个表生成“插入”存储过程。它还处理为具有标识列的表返回新id。它使用SQL SMO。其中一些对我的项目有点具体,所以如果您有任何问题,请告诉我。

    void InsertScripts(Database db)
    {
        var tables = db.Tables.ToIEnumerable(); //this is an extension method to convert Database.Tables into an IEnumerable<Table>             
        {

            foreach (var t in tables)
            {
                var sb = new StringBuilder();
                var sp = new StoredProcedure(db, "gen_insert_" + t.Name);

                sp.AnsiNullsStatus = false;
                sp.QuotedIdentifierStatus = false;
                sp.TextMode = false;                    

                var columns = t.Columns.ToIEnumerable().Where(c => !c.Identity && !c.IsReadOnly()).ToList();

                foreach (var c in columns)
                {
                    var p = new StoredProcedureParameter(sp, "@" + t.Name + "_" + c.Name, c.DataType);                        

                    p.IsCursorParameter = false;


                    if(c.Default != null && c.Default.Length > 0)
                        p.DefaultValue = c.Default;

                    if (c.Nullable)
                        p.DefaultValue = "NULL";


                    sp.Parameters.Add(p);                        

                }


                var cols = string.Join(",", columns.Select(c => c.Name).ToArray());
                var vals = string.Join(",", columns.Select(c => "@" + t.Name + "_" + c.Name).ToArray());


                var sql = string.Format("insert into {0} ({1}) values ({2});", t.Name, cols, vals);

                sb.AppendLine(sql);

                if (t.Columns.ToIEnumerable().Any(c => c.Identity))
                {
                    var declaration = "declare @newid int;\r\n";
                    var ret = "select @newid = scope_identity();\r\nselect @newid;\r\nreturn @newid";

                    sb.Insert(0, declaration);
                    sb.AppendLine(ret);

                }

                sp.TextBody = sb.ToString();

                if(cols.Length > 0 && sp.Parent.StoredProcedures[sp.Name] == null)
                    sp.Create();

            }


        }
    }

public static class Utils //Extension methods...
{
    public static IEnumerable<Table> ToIEnumerable(this TableCollection tables)
    {
        var list = new List<Table>();

        foreach (Table t in tables)
            list.Add(t);

        return list;
    }

    public static IEnumerable<View> ToIEnumerable(this ViewCollection views)
    {
        var list = new List<View>();

        foreach (View v in views)
            list.Add(v);

        return list;
    }

    public static IEnumerable<Column> ToIEnumerable(this ColumnCollection columns)
    {
        var list = new List<Column>();

        foreach (Column c in columns)
            list.Add(c);

        return list;
    }


    public static IEnumerable<ForeignKey> ToIEnumerable(this ForeignKeyCollection columns)
    {
        var list = new List<ForeignKey>();

        foreach (ForeignKey c in columns)
            list.Add(c);

        return list;
    }


    public static IEnumerable<string> ToIEnumerable(this ForeignKeyColumnCollection columns)
    {
        var list = new List<string>();

        foreach (ForeignKeyColumn c in columns)
            list.Add(c.Name);

        return list;
    }
}

答案 1 :(得分:0)

听起来你想要一个ORM,或者你真的想要插入文本而不是插入?

你应该看看Linq To SQL。

答案 2 :(得分:0)

我刚刚编写了一个快速的脏数据导出脚本(对于那些无法通过SSMS访问数据库的时间)。无论如何,这可能有助于未来的人:

var result = new StringBuilder();
using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString)) {
    con.Open();
    using (var cmd = con.CreateCommand()) {
        cmd.CommandText = @"
DECLARE @name VARCHAR(255)
DECLARE iterator CURSOR FOR SELECT name FROM sys.tables WHERE type='U'

OPEN iterator
FETCH NEXT FROM iterator INTO @name
WHILE @@FETCH_STATUS = 0 BEGIN
    SELECT @name name
    EXEC ('SELECT * FROM ' + @name)
    FETCH NEXT FROM iterator INTO @name
END

CLOSE iterator
DEALLOCATE iterator
";
        using (var reader = cmd.ExecuteReader()) {
            do {
                // get table name
                reader.Read();
                string tableName = reader[0].ToString();

                // get contents
                reader.NextResult();
                result
                    .Append("SET IDENTITY_INSERT ")
                    .Append(tableName)
                    .Append(" ON\r\n");
                while (reader.Read()) {
                    result
                        .Append("INSERT ")
                        .Append(tableName)
                        .Append(" (");
                    for (var x = 0; x < reader.FieldCount; x++)
                        result
                            .Append(x == 0 ? string.Empty : ",")
                            .Append("[" + reader.GetName(x) + "]");
                    result
                        .Append(" ) VALUES (");
                    for (var x = 0; x < reader.FieldCount; x++)
                        result
                            .Append(x == 0 ? string.Empty : ",")
                            .Append("'" + reader[x].ToString() + "'");
                    result
                        .Append(")\r\n");
                }
                result
                    .Append("SET IDENTITY_INSERT ")
                    .Append(tableName)
                    .Append(" OFF\r\n");
            } while (reader.NextResult());
        }
    }
}

Response.Write(result);