我正在重写用于在数据库上运行升级的应用程序。基本上,该应用程序的想法是需要一堆脚本(每个版本一个),并在数据库的当前版本和它具有的最新版本之间运行每个脚本。我试图为我们找到一种更好的方式来处理此过程,并且试图使SQL管理对象按照我们需要的方式工作。供参考,这是我必须处理的限制。
这是我目前作为代码使用的内容:
string messages = "";
private void button1_Click(object sender, EventArgs e)
{
string setup = File.ReadAllText(@"[redacted]\Setup.sql");
string script = File.ReadAllText(@"[redacted]\6.3.6002.0.sql");
string script2 = File.ReadAllText(@"[redacted]\6.3.6003.0.sql");
var cnx = new SqlConnection(/*proper connection string*/);
var server = new Server(new ServerConnection(cnx));
//server.ConnectionContext.InfoMessage += ConnectionContext_InfoMessage;
server.ConnectionContext.ServerMessage += ConnectionContext_ServerMessage;
server.ConnectionContext.ExecuteNonQuery(setup);
server.ConnectionContext.ExecuteNonQuery(script);
server.ConnectionContext.ExecuteNonQuery(script2, ExecutionTypes.ContinueOnError);
txtResult.Text = messages;
}
private void ConnectionContext_ServerMessage(object sender, ServerMessageEventArgs e)
{
messages += e.Error.Message + "\r\n";
}
这是我正在使用的脚本:
Setup.sql:
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'UPGRADE_HISTORY')
DROP TABLE UPGRADE_HISTORY
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'TEST_CODE_TABLE')
DROP TABLE TEST_CODE_TABLE
CREATE TABLE UPGRADE_HISTORY (
UPDATE_DATE DATE NOT NULL,
VERSION_TXT VARCHAR(50) NOT NULL,
PRIMARY KEY (UPDATE_DATE, VERSION_TXT)
)
CREATE TABLE TEST_CODE_TABLE (
CODE_VALUE INT PRIMARY KEY,
DESCRIPTION_TXT VARCHAR(250) NOT NULL
)
INSERT INTO UPGRADE_HISTORY VALUES
(DATEADD(d, -3, GETDATE()), '6.2.5000'),
(DATEADD(d, -1, GETDATE()), '6.2.5001'),
(DATEADD(d, -1, GETDATE()), '6.2.5002'),
(DATEADD(d, -1, GETDATE()), '6.3.6000.0'),
(DATEADD(d, -1, GETDATE()), '6.3.6001.0')
INSERT INTO TEST_CODE_TABLE VALUES
(1001, 'Test Code Table'),
(1002, 'Test Code Table 2')
6.3.6602.0.sql:
INSERT INTO UPGRADE_HISTORY VALUES
(GETDATE(), '6.3.6001.0')
GO
PRINT 'Test Code Table Change'
GO
UPDATE TEST_CODE_TABLE SET DESCRIPTION_TXT = 'Test Code Table Change' WHERE CODE_VALUE = 1002;
GO
6.3.6003.0.sql:
INSERT INTO UPGRADE_HISTORY VALUES
(GETDATE(), '6.3.6003.0')
GO
PRINT 'Test Error'
GO
INSERT INTO CODE_TABLE VALUES (1001, 'Test')
--This will throw an error since this will conflict with the primary key
--of the code table (or you know, because I just noticed it doesn't call
--the right table, it's really relevant since I want it to throw an
--error, w/e what it is)
GO
PRINT 'Second Test Code Table Change'
GO
UPDATE TEST_CODE_TABLE SET DESCRIPTION_TXT = 'Test Code Table Change 2' WHERE CODE_VALUE = 1002;
--We still want this to execute.
GO
这是为了重现我们的更新中可能发生的情况。因此,实际上,设置只是每次都创建重新创建数据库,因此我可以使用相同的脚本,然后第一个升级文件是模拟按预期功能运行的文件,最后是第二个升级文件是模拟升级有错误的文件。这就是问题开始的地方。就目前而言,当我执行第二个脚本时,第一部分运行,然后第二部分运行并出现错误,但我没有收到错误消息。 InfoMessage
和ServerMessage
事件均不会触发。然后,运行第三部分(出错的语句之后的部分),然后得到用于打印的ServerMessage。作为参考,这是我收到的输出:
Test Code Table Change
Test Error
Second Test Code Table Change
错误发生前后的打印,我可以通过仔细检查数据来确认错误之后的UPDATE
语句也已执行。但是,不会因INSERT
语句引发错误的事实而引发任何消息或错误。我们确实需要SMO引发错误,或者触发ServerMessage
事件,或者其他任何事情。是我缺少的东西,还是该框架的缺点。