Sql-Server

是否可以將數據批量插入到具有使用 Always Encrypted 加密的列的表中?

  • July 16, 2021

在 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) 不兼容collat​​ion_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 使用Methodselect * from unencryptedTable將其載入到 encryptedTableSqlBulkCopy.WriteToServer(IDataReader)

如果您對此還有其他問題,請在評論部分發表問題,我會盡力解決:)

引用自:https://dba.stackexchange.com/questions/160577