簡體   English   中英

如何在 C# 中創建動態參數化 SQL 查詢字符串

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM