[英]How to create a Dynamic Parameterized SQL Query String in C#
我最終試圖將我存儲在我的 Function 應用程序中的並發列表中的一些記錄保存到具有參數化值的 SQL 服務器數據庫中,其中一個是加密列(不確定是否相關)。
目前,我正在遍歷每條記錄並提取值、參數化它們並將它們保存到數據庫中; 為每條記錄執行此操作。 不過,據我了解,這是非常低效的,我被告知使用每個記錄的參數化值創建一個字符串,然后將該單個字符串作為 SQL 服務器查詢運行會更有效。
有人可以向我解釋我如何實現這樣的目標,或者我可能弄錯了嗎?
謝謝!
以防萬一它對將來的任何人有所幫助,我最終在很大程度上解決了這個問題。
我仍然無法根據這種使用 DataTables(TVP 或表值參數)和 SqlBulkCopy 的新方法檢查查詢中的重復 PK。
使用 SqlBulkCopy 的原因是因為單獨的 TVP 似乎與保存到包含 Always Encrypted 列的 SQL 表不兼容。 盡管類型定義相同,但我收到了一些奇怪的操作數沖突錯誤。 DataTable 和 TVP 似乎不能很好地與 Encrypted Columns 配合使用。
使用帶有 TVP 的 SqlBulkCopy 似乎是允許我們將數據從 C# 腳本保存到具有始終加密列的 SQL 表的解決方法,將 TVP 用於單個查詢語句以加快處理時間。
using (SqlConnection connection = new SqlConnection(<connection_string>))
{
connection.AccessToken = new VisualStudioCredential().GetToken()
if (connection.State == ConnectionState.Closed)
connection.Open();
// Create a new DataTable - !Important - We also have to Create Table Type in our Database as mentioned in this thread.
DataTable saveBatchTable = new DataTable();
// Add rows to the DataTable
saveBatchTable.Columns.Add("col_1", typeof(string));
saveBatchTable.Columns.Add("col_2", typeof(long));
saveBatchTable.Columns.Add("col_3", typeof(bool));
// Assuming we have a list of records - for each 'record' in our list...
foreach (custObject record in recordList)
{
// and for each index attribute value within each record object...
foreach (long idx in record.index)
{
// Add a row of values corresponding to the columns previously added
saveBatchTable.Rows.Add(record.col1Val, record.col2Val, true)
}
}
saveBatchTable.AcceptChanges();
string stagingTableName = "MyStagingTable"
// Create an empty temporary table with the headers from your Source Table within your DB
using (var cmd = new SqlCommand("SELECT * INTO [" + stagingTableName + "] FROM [<SourceTableName>] WHERE 1 = 2;", connection))
{
cmd.ExecuteNonQuery();
}
// Write the DataTable (saveBatchTable) to the new temporary table
using (var bulkCopy = new SqlBulkCopy(connection))
{
bulkCopy.DesintationTableName = "[" + stagingTableName + "]";
bulkCopy.WriteToServer(saveBatchTable);
}
// Store the data within the temporary table to our Source Table then drop the temp table
using (var cmd = new SqlCommand("BEGIN TRAN; INSERT [<SourceTableName>] SELECT * FROM [" + stagingTableName + "]; DROP TABLE [" + stagingTableName + "]; COMMIT", connection))
{
Console.WriteLine("Number of Rows Affected = " + cmd.ExecuteNonQuery().ToString());
}
connection.Close();
}
您可以使用PreparedStatement
,創建一批要插入的行 ( ps.addBatch()
),然后在一個 go ( ps.executeBatch()
) 中插入一批。
樣本:
PreparedStatement ps= con.prepareStatement("INSERT INTO Sample VALUES (?, ?, ?, ?)");
for(int i; i<10; i++){
ps.setString(1, "String1");
ps.setString(2, "String2");
ps.setString(3, "String3");
ps.setInt(4, 1000);
ps.addBatch();
}
ps.executeBatch();
如果要插入很多記錄,您可以創建多個批次並將它們插入循環本身。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.