SQL Server Compact 4.0 因 INSERT 语句而阻塞
我正在尝试用代码创建一个 SQL Server Compact 4.0 数据库,并且我想创建一些系统查找表并用值填充它们。
因此,我有一个 SQL 脚本作为项目中的嵌入式资源,如下所示:
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
我有一些代码来创建和初始化 SQL Server Compact 数据库,归结为:
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();
}
}
所以这段代码基本上枚举了所有嵌入式 SQL脚本并读取它们,然后将 GO
关键字上的内容拆分为子脚本,然后依次执行。
工作正常 - 至少对于 CREATE TABLE
语句......
但是 SQL Server Compact 4.0 在多次插入时会卡住......我尝试在每个 INSERT
行,运气不好 - 仍然窒息。
错误的详细信息是:
System.Data.SqlServerCe.SqlCeException 未处理
消息=解析查询时出错。 [ 令牌行号 = 4,令牌行偏移量 = 1,错误令牌 = INSERT ]
来源=SQL Server Compact ADO.NET 数据提供程序
错误代码=-2147467259
HResult=-2147217900
NativeError=25501
当我在每个 INSERT
语句之间放置一个 GO
语句时,它可以工作 - 但如果我有需要插入数百行的表,那就有点混乱.....
是否有任何技巧/方法可以使 SQL Server Compact 接受并处理单个 SQL 语句块中的多个插入语句?
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??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
没有魔术,只有GO或类似的魔术。使用 SQL Server Compact 一次只能执行一条语句。我的工具可以从现有数据库为您生成 SQL Compact 语句,或者您也可以使用 SqlCeBulkCopy 来快速加载数据。
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.