是否可以將數據批量插入到具有使用 Always Encrypted 加密的列的表中?
在 SSMS 中,我們嘗試將 csv 文件中的大容量插入到具有使用 SQL Server 2016 的 Always Encrypted 功能加密的列的表中。
這是我們正在使用的命令:
INSERT INTO membersE SELECT * FROM OPENROWSET( BULK 'c:\members.csv', FORMATFILE = 'c:\membersEFormat.xml', FIRSTROW = 2 ) m
這將返回您在嘗試插入加密列時遇到的典型錯誤:
消息 206,級別 16,狀態 2,第 6 行
操作數類型沖突:varbinary 與使用 (encryption_type = ‘DETERMINISTIC’,encryption_algorithm_name = ‘AEAD_AES_256_CBC_HMAC_SHA_256’,column_encryption_key_name = ‘CEK_Auto1’,column_encryption_key_database_name = ‘DATABASE’) 加密的 varchar(50) 不兼容collation_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); } }
通過 SSMS 加密的列不支持以您描述的方式進行批量插入操作。
請參閱此 ( https://blogs.msdn.microsoft.com/sqlsecurity/2015/07/28/encrypting-existing-data-with-always-encrypted/ ) 文章將現有數據遷移到 Always Encrypted
另外,請注意,支持通過 C#(.NET 4.6.1+ 客戶端)應用程序進行批量插入。
您可以在 c# 中使用 SqlBulkCopy 專門使用
SqlBulkCopy.WriteToServer(IDataReader)
Method 來執行此操作。我假設您正在嘗試將數據從 csv 文件載入到具有加密列的表(例如 encryptedTable)。我會做以下事情
- 創建一個新表(比如 unencryptedTable,出於安全考慮,您可能會考慮在本地 sql server 實例中創建此表),其架構相同,沒有任何列加密。
- 使用您在問題中描述的方法將 csv 數據載入到 unencryptedTable
- 將數據載入到 SqlDataReader 中,然後使用 SqlBulkCopy 使用Method
select * from unencryptedTable
將其載入到 encryptedTableSqlBulkCopy.WriteToServer(IDataReader)
如果您對此還有其他問題,請在評論部分發表問題,我會盡力解決:)