簡體   English   中英

SSIS 腳本任務拋出死鎖錯誤

[英]SSIS Script Task is throwing deadlock error

我正在嘗試查詢數據庫並將內容發送到 email 的正文中。 我嘗試在此處關注我的用例。 但是當我嘗試運行 package 時,它會引發死鎖錯誤。 誰能建議我錯過了什么

腳本如下

namespace ST_ac39a1a4cb6047819cc46d683db46ac6
{
    [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {

        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        }

        public void Main()
        {
            Variables varCollection = null;

            string User_Recepient_Email_ID = Dts.Variables["User::UserEml"].Value.ToString();

            Dts.VariableDispenser.LockForWrite("User::EmailData");
            Dts.VariableDispenser.GetVariables(ref varCollection);
            var data = varCollection["User::EmailData"].Value;

            OleDbDataAdapter da = new OleDbDataAdapter();
            DataTable dt = new DataTable();
            da.Fill(dt, varCollection["User::EmailData"].Value);

            SendMailMessage("loadJob@xyz.com", User_Recepient_Email_ID, "ETL Load Status Report", ConvertDataTableToHTML(dt), true, "smtp.xxxxxxxx.org");

            Dts.TaskResult = (int)ScriptResults.Success;
        }


        public static string ConvertDataTableToHTML(DataTable dt)
        {
            string html = "<table border ='1'>";
            //add header row
            html += "<tr>";
            for (int i = 0; i < dt.Columns.Count; i++)
                html += "<th>" + dt.Columns[i].ColumnName + "</th>";
            html += "</tr>";
            //add rows
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                html += "<tr style='color:blue;'>";
                for (int j = 0; j < dt.Columns.Count; j++)
                    html += "<td>" + dt.Rows[i][j].ToString() + "</td>";
                html += "</tr>";
            }
            html += "</table>";
            return html;
        }
        private void SendMailMessage(string From, string SendTo, string Subject, string Body, bool IsBodyHtml, string Server)
        {
            MailMessage htmlMessage;
            SmtpClient mySmtpClient;

            htmlMessage = new MailMessage(From, SendTo, Subject, Body);
            htmlMessage.IsBodyHtml = IsBodyHtml;

            mySmtpClient = new SmtpClient(Server);
            mySmtpClient.Credentials = CredentialCache.DefaultNetworkCredentials;
            mySmtpClient.Send(htmlMessage);
        }   
    }
}

和任務腳本屬性

在此處輸入圖像描述

運行 package 時,錯誤是

錯誤:腳本任務中的 0xC001405C:嘗試鎖定變量“User::EmailData”以進行讀/寫訪問時檢測到死鎖。 嘗試 16 次后無法獲取鎖。 鎖超時。`

錯誤:腳本任務中的 0xC001405D:嘗試鎖定變量“System::InteractiveMode”以進行讀訪問和變量“User::EmailData”進行讀/寫訪問時檢測到死鎖。 嘗試 16 次后無法獲取鎖。 鎖超時。

錯誤:腳本任務中的 0x1:嘗試鎖定變量“User::EmailData”以進行讀/寫訪問時檢測到死鎖。 嘗試 16 次后無法獲取鎖。 鎖超時。 任務失敗:腳本任務

警告:0x80019002 在 Foreach 循環每個用戶:SSIS 警告代碼 DTS_W_MAXIMUMERRORCOUNTREACHED。 Execution 方法成功,但引發的錯誤數 (5) 達到了允許的最大值 (1); 導致失敗。 當錯誤數量達到 MaximumErrorCount 中指定的數量時,就會發生這種情況。 更改 MaximumErrorCount 或修復錯誤。 警告:SurplusMouse_EmailOrderDetail 處的 0x80019002:SSIS 警告代碼 DTS_W_MAXIMUMERRORCOUNTREACHED。 Execution 方法成功,但引發的錯誤數 (5) 達到了允許的最大值 (1); 導致失敗。 當錯誤數量達到 MaximumErrorCount 中指定的數量時,就會發生這種情況。 更改 MaximumErrorCount 或修復錯誤。 SSIS package

編輯

下面是查詢

SELECT cus.CustomerNumber as CustomerNumber,cus.Location as ReceivingLocation, 
       i.StrainName as StrainName,i.StrainCode as StrainCode,i.Age as Age,
       i.Sex as Sex,i.Genotype as Genotype,i.RoomNumber as SentFrom,io.OrderQuantity as OrderQuantity
FROM [dbo].[MouseOrder] mo
JOIN [dbo].[Customer] cus on cus.Customer_ID = mo.CustomerId
JOIN [dbo].[InventoryOrder] io on io.OrderId = mo.MouseOrder_ID
JOIN [dbo].[Inventory] i on i.Inventory_ID =  io.InventoryId 
WHERE mo.OrderDate = convert(date,getdate() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time') and mo.SAMAccountEmail = ?

有更好的方法。

腳步:

  1. 創建 SQL 服務器存儲過程,該過程將通過 XML/XQuery 為 email 生成 (X)HTML 正文。
  2. 通過SSIS 調用該 sp 執行 SQL任務並將其 output 分配給 ZD941Z 變量239618BCC103D28BA9618BCC103D2。
  3. 調用SSIS 腳本任務,傳遞來自步驟 #2 的變量,該變量包含 (X)HTML email 正文以發送 email。

好處:

  • 沒有字符串連接。
  • 不用擔心 NULL 值。
  • 非常容易創建,非常容易維護。
  • UI 樣式通過 CSS 控制。

這是一個概念性的例子。

SQL

DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, [Name] VARCHAR(20), Number CHAR(5), [Address] VARCHAR(100));
INSERT INTO @tbl (Name, Number, Address) VALUES
('Bob  ', '12345' ,'1 Street, Town'),
('John ', '23456' , NULL),
('Scott', '34567' ,'3 Avenue, City');

DECLARE @xhtmlBody XML
   , @body NVARCHAR(MAX)
   , @tableCaption VARCHAR(30) = 'Customers list';

SET @xhtmlBody = (SELECT (
SELECT * FROM @tbl 
FOR XML PATH('row'), TYPE, ROOT('root'))
.query('<html><head>
            <meta charset="utf-8"/>
            (: including embedded CSS styling :)
            <style>
            table <![CDATA[ {border-collapse: collapse;  width: 300px;} ]]>
            th <![CDATA[ {background-color: #4CAF50; color: white;} ]]>
            th, td <![CDATA[ { text-align: left; padding: 8px;} ]]>
            tr:nth-child(even) <![CDATA[ {background-color: #f2f2f2;} ]]>
            #green <![CDATA[ {background-color: lightgreen;} ]]>
         </style>
         </head>
         <body>
<table border="1">
   <caption><h2>{sql:variable("@tableCaption")}</h2></caption>
   <thead>
      <tr>
        <th>No.</th>
        <th>Name</th>
        <th>Number</th>
        <th>Address</th>
      </tr>
   </thead>
   <tbody>
{
    for $row in /root/row
    return <tr>
            <td>{data($row/ID)}</td>
            <td>{data($row/Name)}</td>
            <td>{data($row/Number)}</td>
            <td>{data($row/Address)}</td>
        </tr>
}
</tbody></table></body></html>'));

SELECT @xhtmlBody;

SET @body = CAST(@xhtmlBody AS NVARCHAR(MAX));

使用你得到的東西,錯誤是從你與變量交互的方式中蔓延出來的。 您提供的代碼是他在 2005 時代必須做的事情,盡管當時 VB.NET 因為 C# 不是一個選項。 您應該能夠通過 Dts.Variables 集合直接訪問變量,然后根據需要獲取它們的Value - 轉換為字符串或保留為 object 類型。

        string User_Recepient_Email_ID = Dts.Variables["User::UserEml"].Value.ToString();
        var data = Dts.Variables["User::EmailData"].Value;

        OleDbDataAdapter da = new OleDbDataAdapter();
        DataTable dt = new DataTable();
        da.Fill(dt, data);

看起來您實際上並沒有寫入這些值,所以我會在第一個屏幕截圖中將它們從 ReadWrite 更改為 ReadOnly。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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