将SQL Server表的数据复制到新表(在代码中)

时间:2014-03-22 19:19:37

标签: sql-server vb.net entity-framework ef-code-first

我可以在表格之间复制数据的方法上使用您的建议。我真的试图避免使用特定于RDBMS的SQL ......除了名称之外,这两个表在所有方面都是相同的。

概念:

我的应用程序使用表格中的数据(让我们称之为TableA)。但是这个参考数据几乎每天都在变化,所以我想复制昨天关闭以便为数据提供空间。

现在,我使用SMO制作TableA(架构)的精确副本,其中包含表,索引,键等的唯一(使用日期)名称。没有问题。如果使用今天的数据更新TableA时出现任何问题,我可以随时恢复TableA TableA_<yesterdayDate>.rename)。两个表都在同一个数据库中。

我不能只使用SMO的DbContext,因为它不会重命名所有按键&amp;指数......

这个前提非常重要。

所需:

非SQL语句的方法。我在这个应用程序中投入了大量的EF6 / Code First,但随着表格的名称每天都在变化,我无法在DbContext中添加表格/类别以防万一&#39 ;

我只是觉得 dirty 使用低级SQL ...

  • SQL Server 2012
  • VB2012
  • EF6 / Code First

P.S。我过去曾尝试过几次通过{{1}}实现SQL语句(LINQ-ish),并且从来没有让它工作 - 特别是对于SP。

1 个答案:

答案 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在这个早期阶段非常实用......

我仍然对创意持开放态度,但我尽可能地挖掘,我必须继续前进。也许我会重新访问一些更优雅的东西!