我可以在表格之间复制数据的方法上使用您的建议。我真的试图避免使用特定于RDBMS的SQL ......除了名称之外,这两个表在所有方面都是相同的。
概念:
我的应用程序使用表格中的数据(让我们称之为TableA
)。但是这个参考数据几乎每天都在变化,所以我想复制昨天关闭以便为数据提供空间。
现在,我使用SMO制作TableA
(架构)的精确副本,其中包含表,索引,键等的唯一(使用日期)名称。没有问题。如果使用今天的数据更新TableA
时出现任何问题,我可以随时恢复TableA
TableA_<yesterdayDate>
(.rename
)。两个表都在同一个数据库中。
我不能只使用SMO的DbContext
,因为它不会重命名所有按键&amp;指数......
这个前提非常重要。
所需:
非SQL语句的方法。我在这个应用程序中投入了大量的EF6 / Code First,但随着表格的名称每天都在变化,我无法在DbContext
中添加表格/类别以防万一&#39 ;
我只是觉得 dirty 使用低级SQL ...
P.S。我过去曾尝试过几次通过{{1}}实现SQL语句(LINQ-ish),并且从来没有让它工作 - 特别是对于SP。
答案 0 :(得分:0)
我找不到更清洁的方法来做到这一点。我试图将所有逻辑封装到一个Function中,该Function在成功/失败时返回一个布尔值。请原谅代码的粗糙度!
NewTableName只是 OldTableName_YYYMMDD 。我本可以使用&#34; SourceTableName&#34;,但这只是它的第一次黑客攻击。
Public Function MoveAllRowsToNewTable(OldTableName As String, NewSchemaName As String, NewTableName As String, IndexColumnName As String) As Boolean
' OldTableName = "TableA", "TableB", ...
' NewSchemaName = "dbo"
' NewTableName = "TableA_20140325", etc.
' IndexColumnName = "ID" in my case, but whatever col is needed
'
Try
'===
'
' DROP target table (if exist)
'
If Me.DoesTableExist(NewSchemaName, NewTableName) Then
Dim CmdQ = Me.ctx.Database.ExecuteSqlCommand("DROP TABLE " & NewSchemaName & "." & NewTableName)
log.Debug("DROPPED TABLE " & NewTableName)
Else
NewTableName = NewSchemaName & "." & NewTableName
log.Debug("New table name: " & NewTableName)
End If
'
Dim numRows As Int32 = 0 ' holds # of rows in SourceTable to check if copy OK
Select Case OldTableName
Case "TableA"
Try
'===
'
' Count rows in source table
'
numRows = (Me.ctx.TableA).Count
'
'===
'
' Copy rows in source table, creating new table in the process
'
CmdQ = "SELECT * INTO " & NewTableName & " FROM " & OldTableName
Me.ctx.Database.ExecuteSqlCommand(CmdQ)
'
' create PK
'
Dim PKQ As String = "ALTER TABLE " & NewTableName & " ADD CONSTRAINT PK_" & NewTableName & "_ID PRIMARY KEY CLUSTERED (ID)"
CmdQ = ctx.Database.ExecuteSqlCommand(PKQ.ToString)
'
' create index
'
Dim NewTableIndexName As String = "idx_" & NewTableName.Replace(".", "_") ' indices can't have a '.' in them
Dim IdxQ As String = "CREATE INDEX " & NewTableIndexName & " ON " & NewTableName & " (" & IndexColumnName & ");"
CmdQ = ctx.Database.ExecuteSqlCommand(IdxQ.ToString)
'
' verify rows copied
'
Dim RowQ As Int32 = Me.ctx.Database.SqlQuery(Of Int32)("SELECT COUNT(*) AS rows FROM " & NewTableName).FirstOrDefault
log.Debug("TargetTableRows: " & RowQ.ToString)
If numRows = RowQ Then
log.Debug("MATCH!" & RowQ)
Else
log.Debug("NO MATCH! numRows: " & numRows & " RowQ: " & RowQ)
'
' rollback the move-the copy FAILED!
'
' XXX to-do
End If
Catch ex As Exception
[...]
End Try
'
Case "TableB"
[...]
我只有3个源表,所以Switch / Case在这个早期阶段非常实用......
我仍然对创意持开放态度,但我尽可能地挖掘,我必须继续前进。也许我会重新访问一些更优雅的东西!