2016-11-25 60 views
0

總之,我有一個CLR方法用於從SQL Server向用戶發送電子郵件。我在我的SQL Server表中擁有關於正文,附件,主題,電子郵件等的所有數據信息。那麼,我正在C#中做一個應用程序來做到這一點,我沒有用表格中存儲過程保存信息的麻煩,但是當我想執行我的SP發送ID(郵件)時。這說'命令成功完成',但郵件不發送。然後我測試從SQL Server手動執行我的SP,並正確發送一些ID,有些不'監視'我的發送方法,因爲這樣可以正確執行命令,但是執行任何操作。爲什麼發生這種情況?有人有此問題之前?爲什麼我的存儲過程沒有用某個id執行CLR方法?

這是我的CLR方法

[SqlProcedure] 
    public static int CustomMethod(int id_email, out string sError) 
    { 
     int mReturn = 0; 
     DataSet ds = new DataSet(); 
     sError = string.Empty; 
     Dictionary<int, string> ListFile = new Dictionary<int, string>(); 
     try 
     {     
      ds = retornarQuery(strQuery: "ZeusFW_Email_List " + id_email); 
      if (ds.Tables[0].Rows.Count > 0) 
      { 
       for (int i = 0; i <= ds.Tables[0].Rows.Count - 1; i++) 
       { 
        DataRow row = ds.Tables[0].Rows[i]; 
        string ds_to_name = (string)row["ds_to_name"]; 
        string ds_to_email = (string)row["ds_to_email"]; 
        string ds_cc_email = (string)row["ds_cc_email"]; 
        string ds_bcc_email = (string)row["ds_bcc_email"]; 
        string ds_idiom = (string)row["ds_idiom"]; 
        string ds_subject = (string)row["ds_subject"]; 
        string ds_body = (string)row["ds_body"]; 
        int am_sent_times = (int)row["am_sent_times"]; 
        int in_process = (int)row["in_process"]; 
        int am_email_port = (int)row["am_email_port"]; 
        string ds_email_host = (string)row["ds_email_host"]; 
        string ds_email_user = (string)row["ds_email_user"]; 
        string ds_email_password = (string)row["ds_email_password"]; 
        int am_email_html = (int)row["am_email_html"]; 
        int am_email_ssl = (int)row["am_email_ssl"]; 
        string ds_email_name = (string)row["ds_email_name"]; 
        string ds_email_xsl = (string)row["ds_email_xsl"]; 
        int in_email_log = (int)row["in_email_log"]; 
        DeliveryNotificationOptions am_notificationoptions = NotificationOptions((int)row["am_notificationoptions"]); 
        MailPriority am_priority = Priority((int)row["am_priority"]); 
        if (in_process == 0 && am_email_html == 1) 
        { 
         ds_body = DoXSLT(ds_body, ds_email_xsl); 
        } 
        ZeusFrameworkSmtp.ZeusFrameworkSmtp email = new ZeusFrameworkSmtp.ZeusFrameworkSmtp(); 
        email.AddFrom = ds_email_user; 
        email.AddName = ds_email_name; 
        email.AddTo.Add(ds_to_email); 
        if (ds_cc_email != null || !ds_cc_email.Equals("")) email.AddCC = ds_cc_email; 
        if (ds_bcc_email != null || !ds_bcc_email.Equals("")) email.AddBcc = ds_bcc_email; 
        if (am_sent_times > 0) { ds_subject = "Re#" + am_sent_times + " " + ds_subject; } 
        email.Subject = ds_subject; 
        email.Body = ds_body; 
        email.BodyHtml = (am_email_html == 0 ? false : true); 
        email.Server = ds_email_host; 
        email.Port = am_email_port; 
        email.User = ds_email_user; 
        email.Password = ds_email_password; 
        email.EnableSsl = (am_email_ssl == 0 ? false : true); ; 
        email.NotificationOptions = am_notificationoptions; 
        email.Priority = am_priority; 
        am_sent_times = am_sent_times + 1; 
        if (ds.Tables[1].Rows.Count > 0) 
        { 
         for (int j = 0; j <= ds.Tables[1].Rows.Count - 1; j++) 
         { 
          DataRow rowAttachments = ds.Tables[1].Rows[j]; 
          if (id_email == (int)rowAttachments["id_email"]) 
          { 
           if ((int)rowAttachments["in_delete_file"] == 1) ListFile.Add(j, (string)rowAttachments["ds_full_path"]); 
           email.AddAttachments.Add((string)rowAttachments["ds_full_path"]); 
          } 
         } 
        } 
        bool bresult = email.Send(out sError); 
        //if (bresult) { mReturn = 1; Database.ZeusFW_Email_Update(id_email, am_sent_times, sError, in_email_log).Run(); } 
        if (string.IsNullOrEmpty(sError) || sError.Equals("ESTOY EJECUTANDO EL METODO")) sError = "Operación completada con éxito."; 
        if (ListFile.Count > 0) 
        { 
         foreach (KeyValuePair<int, string> item in ListFile) 
         { 
          if (item.Key == 1) File.Delete(item.Value.ToString()); 
         } 
         ListFile.Clear(); 
        } 
       } 
      } 
      else sError = "No se encontró el ID"; 
     } 
     catch (Exception ex) 
     { 
      StringBuilder s = new StringBuilder(); 
      //sError = sError + "-" + "Error executing SQL statement information: " + ex.Message + "id_email : " + id_email.ToString() + "Conn : " + Database.ConnectionString + ex.StackTrace.ToString(); 

      LogWindows _LogWindows = new LogWindows(); 
      _LogWindows.Save("Zeus", sError, System.Diagnostics.EventLogEntryType.Error); 
      //SqlContext.Pipe.Send("Error executing SQL statement information: " + ex.Message + "id_email> " + id_email_aux.ToString() + "Conn>" + Database.ConnectionString); 
     } 
     return mReturn; 
    } 

這是我的存儲過程

CREATE PROCEDURE [dbo].[CustomMethod] 
@id_email int 
,@sError nvarchar(2000)=NULL OUTPUT 
WITH EXECUTE AS CALLER 
AS 
EXTERNAL NAME [AssemblyNamespace].[AssemblyNamespace.AssemblyNamespace1].[CustomMethod] 
GO 

Don't Work Work perfect

這兩個ID在我的SQL表中存在類似的有效郵件。忽略SP的名稱是私有化,他們在CLR方法和存儲過程中有相同的名稱

我在SQL Server中有這個異常。

男裝6522,NIVEL 16,埃斯塔1,Procedimiento ZeusFW_EmailqueueUnit_SendOutError,拉利內阿用戶定義例程或聚合 「ZeusFW_EmailqueueUnit_SendOutError」 的執行過程中出現2
一個.NET Framework錯誤:

System.IO.IOException :El sistema no puede ponerse en contacto con un controlador de dominio para que atienda la solicitud deautenticación。 Inténtelode nuevomástarde。

System.IO.IOException:
EN System.IO .__ Error.WinIOError(的Int32的errorCode,字符串maybeFullPath)
EN System.IO.FileStream.Init(字符串路徑,模式的FileMode,FileAccess的訪問,的Int32權利,布爾useRights,FileShare共享,Int32 bufferSize,FileOptions選項,SECURITY_ATTRIBUTES secAttrs,字符串msgPath,布爾bFromProxy)
System.IO.FileStream..ctor(字符串路徑,FileMode模式,FileAccess訪問,FileShare共享,Int32 bufferSize,FileOptions選項,String msgPath,Boolean bFromProxy)
System.IO.FileStream..ctor(String path,FileMode mode,FileAccess access,FileShare share)
烯System.Net.Mail.AttachmentBase.SetContentFromFile(字符串文件名,字符串mediaType的)
烯System.Net.Mail.Attachment..ctor(字符串文件名)
烯ZeusFrameworkSmtp.ZeusFrameworkSmtp.Send(字符串&誤差)
恩AssemblyZeusSMTP.AssemblyZeusSMTP.ZeusFW_EmailqueueUnit_SendOutError(SqlInt32 id_email,的SqlString & sError)

+3

我們可以看看你的代碼,如果你發佈它。 –

+0

我有錯誤。當我從我的應用程序中使用CLR時,會拋出異常System.IO.Exception:系統無法聯繫域控制器來處理身份驗證請求。稍後嘗試Somones知道爲什麼會發生?當我從sql服務器手動插入一行並執行我的sp時,發送正確 –

回答

3

這裏有一些事情看:

  1. 請使用Sql*類型來代替SQLCLR公共方法的輸入和輸出參數的本機.NET類型。所以它的簽名應該是:

    public static SqlInt32 CustomMethod(SqlInt32 id_email, out SqlString sError) 
    

    您可以通過.Value屬性,它們都具有(例如id_email.Value)獲得本地值出這些類型的任何。

  2. 你經歷了傳回狀態碼的麻煩,所以抓住它,讓你可以看到更多的事情。在C#代碼,基於bresult非零值賦給mReturn

    if (bresult) 
    { 
        mReturn = 1; 
    } 
    else 
    { 
        mReturn = 2; 
    } 
    

    ,然後改變你的T-SQL是:

    DECLARE @id_email INT, 
         @sError NVARCHAR(4000), 
         @return_code INT; 
    
    SET @id_email = 37; 
    
    EXEC @return_code = dbo.ZeusFW_EmailQueueUnit_SendOutError 
         @id_email, 
         @sError OUTPUT; 
    
    SELECT @return_code AS [ReturnCode], 
         N'~' + @sError + N'~' AS [ErrorMessage], 
         DATALENGTH(@sError) AS [ErrorMessageBytes]; 
    
  3. 在發佈代碼來看,似乎喜歡的唯一途徑得到一個空字符串@sError(?是不是真的空)是:

    1. email.Send()實際上是傳回的白色空間的一個非空字符串nd /或其他不可打印的字符。上面顯示的T-SQL已經過調整以檢查這一點。
    2. 代碼正在發生異常,在這種情況下,您應該在Windows事件日誌中看到某些內容(因爲您正在保存一個條目)。你檢查過Windows事件日誌嗎?
  4. Zeus框架中是否有任何日誌記錄可以檢查?
  5. 最重要的是:爲什麼你要發送SQLCLR的電子郵件時,SQL Server有一個內置函數,這是一個異步?它可以處理文件附件,HTML電子郵件正文等。請考慮更換此調用sp_send_dbmail(SQL Server 2008中引入的T-SQL存儲過程或甚至可能是2005)的此SQLCLR存儲過程。

其他說明:

  • 生活會更容易,而且代碼的可讀性,如果你停止使用的數據類型前綴變量。因此,使用Result而不是mReturn,Result而不是bResultErrorMessage而不是sError。這適用於C#和T-SQL。
  • 沒有必要從Count中減去1,因爲這會迫使您使用<=而不僅僅是<。使用j < ds.Tables[1].Rows.Count在邏輯上是相同的,少一個(不必要的)操作,並且更易讀:-)。
+0

謝謝@srutzky –

+0

我有錯誤。當我從我的應用程序中使用我的CLR時,會拋出一個異常'System.IO.Exception:系統無法聯繫域控制器來處理認證請求。嘗試以後'Somones知道爲什麼會發生?當我從sql服務器手動插入一行並執行我的sp時,它會正確發送。 @srutzky –

+0

@ChristianTorresM您將需要發佈該錯誤消息的整個堆棧跟蹤(IO異常)。它有可能來自Zeus框架。另外,「手動插入一行」與此有什麼關係?您發佈的代碼不顯示任何INSERT命令。 –