2016-11-25 9 views
0

つまり、SQL Serverからユーザーに電子メールを送信するためのCLRメソッドがあります。 SQL Serverテーブルには、本文、添付ファイル、件名、電子メールなどに関するすべてのデータ情報があります。さて、これを行うにはC#でアプリをやっていますが、私はテーブルのストアドプロシージャを使って情報を保存するのに問題はありませんが、SP送信ID(メール)を実行したいときに問題はありません。これは「コマンドが正常に完了しました」と表示されますが、メールは送信されません。それから、私はSPをSQL Serverから手動で実行してテストし、いくつかの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

のは、有効なメールのように私のSQLテーブルに存在両方ID。 SPの名前を無視するのは、CLRメソッドとストアドプロシージャで同じ名前の非公開です。

SQL Serverではこの例外があります。

メンズ6522、ニベル16、エスタード1、Procedimiento ZeusFW_EmailqueueUnit_SendOutError、リネア2
A .NET Frameworkのエラーがユーザ定義のルーチンまたは集計 "ZeusFW_EmailqueueUnit_SendOutError" の実行中に発生した:

System.IO.IOException :エルシステムは、法律上の責任を負いません。 Inténtelode nuevomástarde。

System.IO.IOException:System.IO .__ Error.WinIOError(のInt32のerrorCode、文字列maybeFullPath)
System.IO.FileStream.Init EN(文字列パス、にFileModeモード、FileAccessのアクセス、のInt32権EN
、 String msgPath、Boolean bFromProxy)
System.IO.FileStream..ctor(文字列パス、FileModeモード、FileAccessアクセス、FileShare共有、Int32 bufferSize、FileOptionsオプション) 、String msgPath、Boolean bFromProxy)
System.IO.FileStream..ctor(文字列パス、FileModeモード、FileAccessアクセス、FileShare共有)
EN System.Net.Mail.AttachmentBase.SetContentFromFile(文字ファイル名、文字列のMediaType)
System.Net.Mail.Attachment..ctor EN(文字列filename)
ZeusFrameworkSmtp.ZeusFrameworkSmtp.Send EN(文字列&エラー)
ここでAssemblyZeusSMTP.AssemblyZeusSMTP.ZeusFW_EmailqueueUnit_SendOutErrorエン(たSqlInt32 id_email、たSqlString & sError)

+3

投稿するとコードを見ることができます。 –

+0

私はエラーがあります。私のアプリから私のCLRを借用すると、例外がスローされます。System.IO.Exception:システムは、認証要求を処理するためにドメインコントローラに接続できません。後で試してくださいSomonesはなぜ起きているのか知っていますか? SQL Serverから手動で行を挿入してspを実行すると、正しく送信されます。 –

答えて

3

を見ていくつかのものです:

  1. SQLCLRパブリックメソッドの入出力パラメータにネイティブ.NETタイプの代わりにSql*タイプを使用してください。だから、署名は次のようになります。

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

    あなたは彼らのすべてが(例えばid_email.Value)を持っている.Valueプロパティを経由して、これらのタイプのいずれかのうち、本来の値を取得することができます。

  2. あなたは状態コードを返すという手間を経たので、何が起こっているのかをもっと見ることができます。

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

    をそしてあるためにあなたのT-SQLを変更:C#コードでは、bresultに基づいてmReturnにゼロ以外の値を割り当てる

    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()は実際に戻って空白aの非空の文字列を渡していますnd /または他の印刷不能文字。上記のT-SQLは、これを確認するために調整されています。
    2. コードに例外が発生しています。この場合、Windowsイベントログに何かが表示されるはずです(そこにエントリを保存しているため)。あなたはWindowsイベントログをチェックしましたか?
  4. 確認できるZeusフレームワークのログはありますか?
  5. 最も重要なのはなぜSQL Serverにこの機能の組み込み関数(非同期)がある場合、SQLCLRから電子メールを送信するのですか?添付ファイル、HTML電子メール本文などを処理できます。sp_send_dbmail(SQL Server 2008で導入された、おそらく2005年でもあります)を呼び出すT-SQLストアドプロシージャのSQLCLRストアドプロシージャを交換してください。

その他の注意事項:あなたはデータ型を持つ変数を接頭辞停止した場合

  • 人生は、より読みやすく簡単に、そしてあなたのコードになります。したがって、bResultの代わりにmReturn,Resultの代わりにResultを使用し、sErrorの代わりにErrorMessageを使用してください。これはC#とT-SQLの両方で動作するようになります。
  • ループの中でCountから1を差し引く必要はありません。そのため、<の代わりに<=を使用する必要があります。 j < ds.Tables[1].Rows.Countを使用することは、論理的には同じであり、1つ少ない(不要な)操作であり、より読みやすい:-)です。
+0

ありがとうございます@srutzky –

+0

エラーが発生しました。私のアプリケーションから私のCLRを借用すると、例外がスローされます。「System.IO.Exception:Systemは認証要求を処理するためにドメインコントローラに接続できません。後で試してくださいSomonesはなぜ起きているのか知っていますか? SQL Serverから手動で行を挿入してspを実行すると、正しく送信されます。 @srutzky –

+0

@ChristianTorresMそのエラーメッセージ(IO例外)のスタックトレース全体をポストする必要があります。Zeusフレームワークから来ている可能性があります。また、「行を手動で挿入する」とは何が関係していますか?投稿したコードにはINSERTコマンドが表示されません。 –

関連する問題