我的公司正在将我们的SQL数据库迁移到云中(Azure和AWS取决于客户端/地区(,因此SQL服务器本地日期时间不再有意义,我们希望使用UTC日期时间。我需要识别所有使用GETDATE()
的数据库对象(主要是存储过程和函数(。我必须自动化这个过程,因为每个数据库都包含数千个对象,而且我们有许多数据库要迁移。最初,出于审核目的,我们仅将此更改应用于大多数表中的CreatedDate
和ModifiedDate
列。
循序渐进:
- (完成(标识包含CreatedDate和ModifiedDate列的所有表
- (已完成(确定引用步骤1中找到的表的所有SQL对象
- Regex每个引用,查看它是否正在更新或插入到具有
GETDATE()
的表中
步骤3是我陷入困境的地方。每个数据库的INSERT
和UPDATE
语句的格式不一致,因为许多开发人员已经开发了几十年的系统。我有一个regex,它部分工作,但无法识别一些多行语句。
我是Regex的初学者,所以为了让自己更容易,我把Regex分成了多个步骤。我在.NET中使用RegexOptions.IgnoreCase
进行所有操作。
第一步是识别引用是否包含INSERT
或UPDATE
。这个正则表达式运行良好,与我的测试输入中的所有示例都匹配。
(inserts*into|update)s*(MySchema.MyTable|MySchema.[MyTable]|[MySchema].MyTable|[MySchema].[MyTable])
第二步是检查INSERT
或UPDATE
语句是否正在使用GETDATE()
。我的Regex部分工作,但无法识别多行语句。我在这里做错了什么?
valuess*((s|.*)getdate()(s|.*))|SETs*.*=s*getdate()
我遇到的第二个问题是将这两个regex语句合并为一个用s*.*
分隔的语句。将这两个语句组合在一起会破坏以前为每个regex语句单独工作的一些功能。
(inserts*into|update)s*(MySchema.MyTable|MySchema.[MyTable]|[MySchema].MyTable|[MySchema].[MyTable])s*.*valuess*((s|.*)getdate()(s|.*))|SETs*.*=s*getdate()
我的样本输入以复制结果:
INSERT INTO [MySchema].[MyTable] (ID, ObjectValue, ObjectData, Col4, CreatedDate, CreatedBy, LastModified, LastModifiedBy) VALUES (3, 'Hello', 'World', 12.32, GETDATE(), @CreatedBy, GETDATE(), @CreatedBy)
INSERT INTO MySchema.MyTable (ID, ObjectValue, ObjectData, Col4, CreatedDate, CreatedBy, LastModified, LastModifiedBy)
VALUES (3, 'Hello', 'World', 12.32, GETDATE(), @CreatedBy, GETDATE(), @CreatedBy)
INSERT INTO
MySchema.MyTable
(ID, ObjectValue, ObjectData, Col4, CreatedDate, CreatedBy, LastModified, LastModifiedBy)
VALUES
(3, 'Hello', 'World', 12.32, GETDATE(), @CreatedBy, GETDATE(), @CreatedBy)
INSERT INTO MySchema.[MyTable] (ID,
ObjectValue,
ObjectData,
Col4,
CreatedDate,
CreatedBy,
LastModified,
LastModifiedBy)
VALUES (3, 'Hello', 'World', 12.32, GETDATE(), @CreatedBy, GETDATE(), @CreatedBy)
INSERT INTO [MySchema].MyTable (ID , ObjectValue, ObjectData, Col4, CreatedDate, CreatedBy, LastModified, LastModifiedBy)
VALUES (
3,
'Hello',
'World',
12.32,
GETDATE(),
@CreatedBy,
GETDATE(),
@CreatedBy
)
UPDATE [MySchema].[MyTable] SET ID = 3, ObjectValue = 'Hello', ObjectData = 'World', Col4 = 12.32, LastModified = GETDATE(), LastModifiedBy = @LastModifiedBy
UPDATE MySchema.MyTable
SET ID = 3, ObjectValue = 'Hello', ObjectData = 'World', Col4 = 12.32, LastModified = GETDATE(), LastModifiedBy = @LastModifiedBy
UPDATE
MySchema.MyTable
SET
ID = 3,
ObjectValue = 'Hello',
ObjectData = 'World',
Col4 = 12.32,
LastModified = GETDATE(),
LastModifiedBy = @LastModifiedBy
UPDATE MySchema.[MyTable] SET ID = 3, ObjectValue = 'Hello', ObjectData = 'World',
Col4 = 12.32, LastModified = GETDATE(), LastModifiedBy = @LastModifiedBy
UPDATE [MySchema].MyTable
SET ID = 3, ObjectValue = 'Hello', ObjectData = 'World', Col4 = 12.32, LastModified = GETDATE(), LastModifiedBy = @LastModifiedBy
SQL server本地日期时间不再有意义,我们希望使用UTC日期时间而不是
Azure使用UTC;将你的数据库放在Azure上,GetDate((将开始返回UTC时间。
不需要更改代码;在Azure上,GetDate((和GetUtcDate((都返回UTC时间
很高兴继续完成您的任务,转而使用GetUtcDate,但我确实想指出,这并不是绝对必要的。。