1

有没有办法将内存数据表(vb.net)及其列(模式)复制到 sql server 新表或现有表中?如果一列已添加到临时表中,是否有办法批量复制将新列添加到现有 sql server 表中的数据?

4

3 回答 3

2

这是我用来将 DataTable 持久化到 SQL Server 的方法,它是用 C# 编写的,但您应该能够很容易地转换它:

public static string CreateCopyTableDataSQLServer(DataTable dt, string tableName, string connectionString)
{
    //Create the Destination Table based upon the structure of the DataTable
    string sql = string.Empty;
    string retValue = string.Empty;
    StringBuilder sbu;

    try
    {
        if (dt.Rows.Count == 0)
        {
            retValue += "The table " + tableName + " was NOT created because the source table contained zero (0) rows of data";
        }
        else
        {
            sbu = new StringBuilder(string.Format("IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[{0}]') AND type in (N'U')) DROP TABLE [dbo].[{0}] ", tableName));
            sbu.Append("Create Table " + tableName + " (");

            string dataType = string.Empty;

            foreach (DataColumn column in dt.Columns)
            {
                switch (column.DataType.Name)
                {
                    case "String":
                        dataType = " nvarchar(MAX) ";
                        break;
                    case "DateTime":
                        dataType = " nvarchar(MAX) ";
                        break;
                    case "Boolean":
                        dataType = " nvarchar(MAX) ";
                        break;
                    case "Int32":
                        dataType = " int ";
                        break;
                    case "Byte[]":
                        dataType = " varbinary(8000) ";
                        break;
                    default:
                        dataType = " nvarchar(MAX) ";
                        break;
                }
                string columnName = column.ColumnName.ToString();
                columnName = columnName.FormatProperNameCase();
                columnName = column.ColumnName.ToString().Replace(" ", "_").Replace("-", "_").Replace("#", "_").FormatRemoveNonLettersNumbers();
                sbu.Append("[" + columnName + "]" + dataType + " null, ");
            }

            sbu.Remove(sbu.Length - 2, 2);
            sbu.Append(")");
            sql = sbu.ToString();
            sql = sql.Replace("/", "_").Replace("\\", "_");

            //Copy the Data From the Data Table into the destination Table that was created above
            bool errorRetValue = SQLServerBulkCopy(dt, sql, tableName, connectionString);

            if (!errorRetValue)
            {
                retValue += " \r\n";
                retValue += "There was an error!";
            }
        }
        return retValue;
    }
    catch (Exception ex)
    {
        retValue = string.Format("Error - There was a problem with table {0} and thus it's data has NOT been transferred - {1}", tableName, ex.Message);
        return retValue;
    }
}

public static bool SQLServerBulkCopy(DataTable dt, string Sql, string TableName, string connectionString, bool connectionTypeSQL = true)
{
    try
    {
        if (connectionTypeSQL)
        {
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();
                using (SqlBulkCopy sqlcpy = new SqlBulkCopy(conn))
                {
                    using (SqlCommand cmd = new SqlCommand(Sql, conn))
                    {
                        cmd.ExecuteNonQuery();
                        sqlcpy.DestinationTableName = TableName;  //copy the datatable to the sql table
                        sqlcpy.WriteToServer(dt);
                    }
                }
            }
            return true;
        }
        else
        {
            throw new ArgumentOutOfRangeException("This method is only for SQL Server Engines");
        }
    }
    catch (Exception ex)
    {
        return false;
    }
}
于 2012-12-18T19:29:47.720 回答
1

用于创建新表:

select  *
into    YourDb.dbo.NewTable
from    #YourTempTable

要附加到现有表:

insert  YourDb.dbo.ExistingTable
select  *
from    #YourTempTable
于 2012-12-18T19:03:05.990 回答
0

在我工作的地方,他们不允许链接服务器,所以我使用 VB.NET 从不同的服务器传输了两个表:

  1. 将源 Sql 表复制到 Datatable 中
  2. 映射数据表中的列
  3. 将 Datatable 复制到目标 Sql 表中

代码如下:

Sub BulkTransferSQLTables(strSchema As String, strTable As String, StrOutputServer As String, StrOutputDatabase As String) ', strEndSrvrDb As String)
    Dim DTBulkTransfer As New DataTable
    'get table of information
    Dim strSchemaTable As String = strSchema & "." & strTable
    Dim sqlstring As String = "Select * from " & strSchemaTable
    Dim Conn As SqlConnection = New SqlConnection("Data Source=" & PubstrServer & ";Initial Catalog=" & PubstrDatabase & ";Integrated Security=True") 'connection to server end
    Dim selectCMD As SqlCommand
    Dim adapter As SqlDataAdapter
    adapter = New SqlDataAdapter(sqlstring, Conn)


    'fill dataset
    Conn.Open()
    adapter.Fill(DTBulkTransfer)

    'Debug.Print(DTBulkTransfer.Rows.Count & " Rows, " & DTBulkTransfer.Columns.Count & " Cols ") 'works


    'build create table statement using details of destination table
    Dim strColname As String
    Dim intRecCount As Integer
    'Dim strSchema As String = "SuffolkPseudo"
    'Dim strTable As String = "Acute_Supporting"
    strSchemaTable = strSchema & "." & strTable
    Dim strCreateTableSQL As String = "CREATE TABLE [" & StrOutputDatabase & "].[" & strSchema & "].[" & strTable & "]("

    Dim strSQL As String = " select [Statement], [RowNo] = ROW_NUMBER() OVER (ORDER BY Statement) FROM [" & PubstrDatabase & "].[dbo].[vwTableAndColumns] " & _
        "where [TABLE_SCHEMA] = '" & strSchema & "' and table_name = '" & strTable & "'"

    Dim strSQL2 As String = "" & _
    " with CTE as ( " & _
    " " & _
    strSQL & _
    " ) " & _
    " " & _
    " select count(*) from CTE "

    intRecCount = GetSQLTableVal(strSQL2)

    For X = 1 To intRecCount
        strSQL2 = "" & _
                " with CTE as ( " & _
                " " & _
                strSQL & _
                " ) " & _
                " " & _
                " select * from CTE "
        strColname = GetSQLTableVal(strSQL2 & " Where [RowNo] = " & X)

        strCreateTableSQL = strCreateTableSQL & " " & Chr(13) & strColname
    Next

    strCreateTableSQL = Microsoft.VisualBasic.Left(strCreateTableSQL, Microsoft.VisualBasic.Len(strCreateTableSQL) - 1) & ") ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]"

    Debug.Print(strCreateTableSQL)


    Conn.Close()

    Dim Conn2 As SqlConnection = New SqlConnection("Data Source=" & StrOutputServer & ";Initial Catalog=" & StrOutputDatabase & ";Integrated Security=True") 'connection to server end


    'create sql string to check if table exists or not.

    strSQL = " select count(*) FROM [" & StrOutputDatabase & "].sys.Tables as t1 " & _
            " inner join [" & StrOutputDatabase & "].sys.schemas as t2 " & _
            " ON t1.schema_id = t2.schema_id" & _
            " where t2.name = '" & strSchema & "' " & _
            " and t1.name = '" & strTable & "'"


    If GetSQLTableValExternalServer(strSQL, StrOutputServer, StrOutputDatabase) > 0 Then

        Conn2.Open()
        'drop old table in destination area and recreate table.
        strSQL = "drop table " & StrOutputDatabase & "." & strSchema & "." & strTable
        selectCMD = New SqlCommand(strSQL, Conn2)
        selectCMD.CommandTimeout = 600
        selectCMD.ExecuteNonQuery()
        Conn2.Close()
    End If

    Conn2.Open()
    'create the table structure 
    selectCMD = New SqlCommand(strCreateTableSQL, Conn2)
    selectCMD.CommandTimeout = 600

    selectCMD.ExecuteNonQuery()


    'list datatable columns 

    Dim name(DTBulkTransfer.Columns.Count) As String
    Dim i As Integer = 0

    'transfer to sql database from datatable to newly created empty detsination table
    Using bulkcopy As SqlBulkCopy = New SqlBulkCopy(Conn2)

        bulkcopy.BulkCopyTimeout = 3000
        bulkcopy.DestinationTableName = strSchemaTable


        For Each column As DataColumn In DTBulkTransfer.Columns
            name(i) = column.ColumnName
            Dim ColMap As New SqlBulkCopyColumnMapping(name(i).ToString, name(i).ToString)
            bulkcopy.ColumnMappings.Add(ColMap)
            Debug.Print("dt COLUMN: " & name(i).ToString)
            i += 1
        Next


        bulkcopy.WriteToServer(DTBulkTransfer)
    End Using

    Conn2.Close()

    MsgBox("Bulk Transfer Complete")


End Sub

谢谢

埃迪·贾德

于 2014-09-04T11:02:38.240 回答