how i can generate programmatically “insert into”

2020-05-05 17:33发布

is there an elegant object-orient based framework?

3条回答
家丑人穷心不美
2楼-- · 2020-05-05 17:43

Here is some code that I wrote for generating 'insert' stored procedures for every table in a database. It also handles returning the new id for those tables that have an identity column. It uses SQL SMO. Some of it is a bit specific to my project so please let me know if you have any questions.

    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;
    }
}
查看更多
手持菜刀,她持情操
3楼-- · 2020-05-05 17:51

I just wrote a quick n dirty data export script (for thoose times you can't access the db via SSMS). Anyway, this might help someone in the future:

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);
查看更多
做个烂人
4楼-- · 2020-05-05 17:54

It sounds like you want an ORM, or do you actually want the insert text rather than inserting?

You should give Linq To SQL a look.

查看更多
登录 后发表回答