是否可以将数据批量插入到具有使用 Always Encrypted 加密的列的表中?

Roa*_*ast 5 sql-server sql-server-2016 always-encrypted bulk-insert

在 SSMS 中,我们尝试将 csv 文件批量插入到具有使用 SQL Server 2016 的始终加密功能加密的列的表中。

这是我们正在使用的命令:

INSERT INTO membersE
SELECT *
FROM OPENROWSET(
    BULK 'c:\members.csv', 
    FORMATFILE = 'c:\membersEFormat.xml',
    FIRSTROW = 2
    ) m
Run Code Online (Sandbox Code Playgroud)

这将返回尝试插入加密列时出现的典型错误:

MSG 206,第16级,状态2,第6行
操作类型冲突:Varbinary与Varchar(50)与(Encryption_Type ='desirctionistist',Encryption_algorithm_name ='aead_aes_aes_aes_aes_aes_256_cbc_hmac_hmac_hmac_sha_256',column_encryetto ='aead_aes_aes_aes_aes_emcy_yerto ='aead_aes_aes_aes_256 ase_name ='数据库')排序规则名称 = 'Latin1_General_BIN2'

我们知道您无法通过 SSMS 插入加密列,并且您需要使用 .NET 4.6.1+ 客户端,但我们想知道批量插入操作是否也无法实现?

对我有用的示例代码
(满足 Windows10 的要求)

        SqlCommand cmd;
        SqlConnection conn;
        SqlBulkCopy copy;
        SqlDataAdapter da;
        DataTable dt;

        using (conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Database"].ConnectionString))
        {
            conn.Open();

            using (cmd = new SqlCommand("SELECT * FROM members", conn))
            using (copy = new SqlBulkCopy(conn))
            using (da = new SqlDataAdapter(cmd))
            using (dt = new DataTable())
            {
                cmd.CommandTimeout = 600;

                da.Fill(dt);

                cmd.CommandText = "TRUNCATE TABLE membersE";
                cmd.ExecuteNonQuery();

                copy.DestinationTableName = "membersE";
                copy.WriteToServer(dt);                    
            }
        }
Run Code Online (Sandbox Code Playgroud)

Nik*_*oft 2

通过 SSMS 的加密列不支持您所描述的批量插入操作。

请参阅此 ( https://blogs.msdn.microsoft.com/sqlsecurity/2015/07/28/encrypting-existing-data-with-always-encrypted/ ) 文章将现有数据迁移到始终加密

另请注意,支持通过 C#(.NET 4.6.1+ 客户端)应用程序进行批量插入。

您可以使用 SqlBulkCopy 在 C# 中执行此操作,特别是使用SqlBulkCopy.WriteToServer(IDataReader)Method。我假设您正在尝试将数据从 csv 文件加载到具有加密列的表(例如加密表)。我会做以下事情

  • 创建一个具有相同架构但没有任何列加密的新表(例如 unencryptedTable,为了安全起见,您可能会考虑在本地 sql server 实例中创建此表)。
  • 使用您在问题中描述的方法将 csv 数据加载到 unencryptedTable 中
  • select * from unencryptedTable数据加载到 SqlDataReader 中,然后使用 SqlBulkCopy 使用SqlBulkCopy.WriteToServer(IDataReader)方法将其加载到加密表中

如果您对此还有其他疑问,请在评论部分提出问题,我会尽力解决:)