sql-server-cesql-server-ce-4insert-statement

SQL Server Compact 4.0 chokes on INSERT statements


I'm trying to create a SQL Server Compact 4.0 database in code, and I would like to create some system lookup tables and fill them with values.

Therefore, I have a SQL script as an embedded resource in my project, which looks like this:

CREATE TABLE SomeType
(TypeID INT NOT NULL CONSTRAINT PK_SomeType PRIMARY KEY,
 TypeDesc NVARCHAR(50) NOT NULL
)
GO

INSERT INTO SomeType(TypeID, TypeDesc) VALUES(10, 'Text for value 10')
INSERT INTO SomeType(TypeID, TypeDesc) VALUES(20, 'Text for value 20')
INSERT INTO SomeType(TypeID, TypeDesc) VALUES(30, 'Text for value 30')
INSERT INTO SomeType(TypeID, TypeDesc) VALUES(40, 'Text for value 40')
INSERT INTO SomeType(TypeID, TypeDesc) VALUES(80, 'Text for value 80')
GO

I have some code to create and initialize the SQL Server Compact database, and it boils down to this:

 using (SqlCeEngine engine = new SqlCeEngine(connectionString))
 {
      engine.CreateDatabase();
      CreateInitialDatabaseObjects(connectionString);
 }

 private void CreateInitialDatabaseObjects(string connectionString)
 {
     using (SqlCeConnection conn = new SqlCeConnection(connectionString))
     {
         List<string> resourceNames = new List<string>(Assembly.GetAssembly(typeof(DatabaseInterface)).GetManifestResourceNames());
         resourceNames.Sort();

         List<string> scripts = new List<string>();

         foreach (string scriptName in resourceNames)
         {
             Stream dbScript = Assembly.GetAssembly(typeof(DatabaseInterface)).GetManifestResourceStream(scriptName);

             if (dbScript != null)
             {
                 string contents = new StreamReader(dbScript).ReadToEnd();

                 string[] splitContents = contents.Split(new string[] {"GO"}, StringSplitOptions.RemoveEmptyEntries);

                 foreach (string split in splitContents)
                 {
                     scripts.Add(split);
                 }
             }
         }

         SqlCeCommand cmd = new SqlCeCommand();
         cmd.Connection = conn;

         conn.Open();

         foreach (string script in scripts)
         {
             cmd.CommandText = script;
             cmd.ExecuteNonQuery();
         }

         conn.Close();
      }
  }

So this code basically enumerates all the embedded SQL scripts and reads them, and then splits that contents on the GO keyword into sub-scripts, which are then executed in turn.

Works fine - at least for the CREATE TABLE statements....

But SQL Server Compact 4.0 chokes on the multiple inserts.... I've tried to add semicolons after each INSERT line, no luck - still chokes.

The details of the error are:

System.Data.SqlServerCe.SqlCeException was unhandled
Message=There was an error parsing the query. [ Token line number = 4,Token line offset = 1,Token in error = INSERT ]
Source=SQL Server Compact ADO.NET Data Provider
ErrorCode=-2147467259
HResult=-2147217900
NativeError=25501

When I put a GO statement between each INSERT statement, it works - but if I have tables that needs hundreds of rows to be inserted, that gets a bit messy.....

Is there any tricks / method to make SQL Server Compact accept and handle multiple insert statements in a single SQL statement block??


Solution

  • There is no magic trick, only GO or similar. You CAN only execute a single statement at a time with SQL Server Compact. My tools can generate the SQL Compact statements for you from an existing db, or you can maybe use SqlCeBulkCopy for fast data loading.