tags:

views:

1483

answers:

3

I'm using sql 2008 express edition and I'm trying to do a multiple row insert thru my C# application.

I've got around 100000 records that needs to be inserted.

Okay all goes well for the first 1000 records then I'm getting the error:

"The number of row value expressions in the INSERT statement exceeds the maximum allowed number of 1000 row values."

I looked at my column data type -> int, so that shouldn't be the problem. I checked my code and I'm inserting in steps of 500 records.

So I googled it but couldn't find anything useful. Can somebody explain why I get this error and if possible how to solve it.

+2  A: 

You can use the SQLBulkCopy class. Which supports batching, transactions and is more efficient than standard insert statements.

Jeremy
"If the source and destination tables are located in the same SQL Server instance, it is easier and faster to use a Transact-SQL INSERT … SELECT statement to copy the data."Source: http://msdn.microsoft.com/en-us/library/s4s223c6.aspxJust for the record. :)
ShdNx
A: 

this is how my code handles the multi insert

var count = "SELECT COUNT(*) as rowcount FROM table_mysql GROUP BY id";

var countReader = Retrieve(count);
var countRows = 0;
try
{
    while (countReader.Read())
    {
        countRows += int.Parse(countReader.GetValue(0).ToString());
    }
}
catch (Exception ex)
{
    Log.LogMessageToFile("Import.cs -> table_mssql: " + ex.StackTrace + " /n" + ex.Message);
}
finally
{
    if (countReader != null) { countReader.Close(); _crud.close_conn(); }
}

for (var a = 0; a < countRows; )
{
    var sql = "SELECT id, traffic_id, dow, uu, imps, impsuu, otsw, otsm FROM table_mysql LIMIT " + a + ", " + (a + 500) + "";

    var reader = Retrieve(sql);
    try
    {
        var builder = new StringBuilder();
        builder.Append(
            "SET IDENTITY_INSERT table_mssql ON;INSERT INTO table_mssql(id, traffic_id, dow, uu, imps, impsuu, otsw, otsm) VALUES ");
        while (reader.Read())
        {
            Application.DoEvents();
            try
            {
                builder.Append("(" + reader.GetValue(0) + ", " + reader.GetValue(1) + ", " +
                               reader.GetValue(2) +
                               ", " + reader.GetValue(3) + ", " + reader.GetValue(4) +
                               ", " + reader.GetValue(5) + ", " + reader.GetValue(6) + ", " +
                               reader.GetValue(7) +
                               "), ");

            }
            catch (Exception ex)
            {
                Log.LogMessageToFile("Import.cs -> table_mssql: " + ex.StackTrace + " /n" + ex.Message);
            }
        }

        var sqlDB = builder.ToString(0, builder.Length - 2);

        sqlDB += ";SET IDENTITY_INSERT table_mssql OFF;";
        if (!InsertDB(sqlDB))
        {
            Log.LogMessageToFile("Import.cs -> table_mssql: No insert happend!");
        }
    }
    catch (Exception ex)
    {
        Log.LogMessageToFile("Import.cs -> table_mssql: " + ex.StackTrace + " /n" + ex.Message);
        return false;
    }
    finally
    {
        if (reader != null)
        {
            reader.Close();
            _crud.close_conn();
        }
    }
    a = a + 500;
}

I'm going to check the sqlbulkcopy. Maybe that is a better solution.

Gerbrand
As lassevk stated above, the limit on that method is 1000 rows. You may want to look into the INSERT INTO tblName SELECT ... FROM otherTbl syntax, since what you're doing seems to come almost directly from another SQL statement. There's no row limit on this.
Eric
A: 

You can take that whole thing down to this:

var sql = "SET IDENTITY_INSERT table_mssql ON;" 
        + "INSERT INTO table_mssql"
        +      "(id, traffic_id, dow, uu, imps, impsuu, otsw, otsm)"
        + " SELECT id, traffic_id, dow, uu, imps, impsuu, otsw, otsm "
        + " FROM table_mysql;"
        + "SET IDENTITY_INSERT table_mssql OFF;";

if (!InsertDB(sqlDB))
{
    Log.LogMessageToFile("Import.cs -> table_mssql: No insert happend!");
}

Also: you should know that Sql Server doesn't support MySql's LIMIT keyword. It uses TOP or ROW_NUMBER instead.

Joel Coehoorn
Is this also applicable when the first query is accessing a mysql database for retrieving the data?I need to transfer data from the mysql database to my local sql server 2008 express.
Gerbrand
Ah, I get your naming convention now. Your code snippet and text of the question make it look like everything is going through the same connection, names or no names. In that case, you will need to hold the data on your client briefly, and BULK_INSERT is by far your fastest option.
Joel Coehoorn
Joel Coehoorn
sorry for the confusion. I left out the comments in my code.Okay, then I will try the bulk_insert.
Gerbrand
The example in the link is with Enterprise Manager and SQL Server 2000, but you should be able to do something similar in Management Studio for 2008.
Joel Coehoorn
It seems not that easy when my program will be installed with our customers :-s?but I also will check it out.
Gerbrand