[英]Why is not my stored procedure executing CLR method with some id's?
In short, I have a CLR method for send emails to users from SQL Server. 简而言之,我有一种CLR方法,用于从SQL Server向用户发送电子邮件。 I have all my data information about body, attachments, subject, emails, etc in my SQL Server tables.
我的SQL Server表中包含有关正文,附件,主题,电子邮件等的所有数据信息。 Well, I'm doing an app in C# to do this, I haven't get troubles for save information with stored procedures in tables but when I want to execute my SP sending id(mail).
好吧,我正在用C#编写一个应用程序来做到这一点,我没有麻烦将信息存储在表中的存储过程中,但是当我想执行SP发送ID(邮件)时。 This says 'Command completed successfully' but mail don't send.
这表示“命令已成功完成”,但邮件未发送。 Then I test executing my SP from SQL Server manually and send correctly some id's and some don't 'watch' my method for send, because this execute commands correctly but do anything.
然后,我测试从SQL Server手动执行SP,并正确发送一些ID,而某些不“监视”我的发送方法,因为这可以正确执行命令,但可以执行任何操作。 Why is happening this?
为什么会这样呢? Someone has have this issue before??
有人以前有这个问题吗?
This is my CLR Method 这是我的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;
}
This my Stored Procedure 这是我的存储过程
CREATE PROCEDURE [dbo].[CustomMethod]
@id_email int
,@sError nvarchar(2000)=NULL OUTPUT
WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [AssemblyNamespace].[AssemblyNamespace.AssemblyNamespace1].[CustomMethod]
GO
Both ID's exist in my sql table like valid mails. 两个ID都像有效邮件一样存在于我的sql表中。 Ignore names of SP is for privacity they have same name in CLR method and Stored Procedure
出于安全考虑,请忽略SP的名称,它们在CLR方法和存储过程中具有相同的名称
I've got this Exception in SQL Server. 我在SQL Server中有此异常。
Mens 6522, Nivel 16, Estado 1, Procedimiento ZeusFW_EmailqueueUnit_SendOutError, Línea 2
Mens 6522,Nivel 16,Estado 1,Procedimiento ZeusFW_EmailqueueUnit_SendOutError,Línea2
A .NET Framework error occurred during execution of user-defined routine or aggregate "ZeusFW_EmailqueueUnit_SendOutError":在执行用户定义的例程或聚合“ ZeusFW_EmailqueueUnit_SendOutError”期间发生.NET Framework错误:
System.IO.IOException: El sistema no puede ponerse en contacto con un controlador de dominio para que atienda la solicitud de autenticación.
System.IO.IOException:紧急情况下的控制权的联系制度。 Inténtelo de nuevo más tarde.
Inténtelode nuevo主要。
System.IO.IOException:
System.IO.IOException:
en System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)zh-cn System.IO .__ Error.WinIOError(Int32 errorCode,可能是StringFullPath)
en System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)zh-cn System.IO.FileStream.Init(字符串路径,FileMode模式,FileAccess访问,Int32权限,布尔useRights,FileShare共享,Int32 bufferSize,FileOptions选项,SECURITY_ATTRIBUTES secAttrs,字符串msgPath,布尔bFromProxy)
en System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)zh-cn System.IO.FileStream..ctor(字符串路径,FileMode模式,FileAccess访问,FileShare共享,Int32 bufferSize,FileOptions选项,String msgPath,布尔bFromProxy)
en System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)zh-cn System.IO.FileStream..ctor(字符串路径,FileMode模式,FileAccess访问,FileShare共享)
en System.Net.Mail.AttachmentBase.SetContentFromFile(String fileName, String mediaType)zh-cn System.Net.Mail.AttachmentBase.SetContentFromFile(字符串fileName,字符串mediaType)
en System.Net.Mail.Attachment..ctor(String fileName)zh-cn System.Net.Mail.Attachment..ctor(字符串fileName)
en ZeusFrameworkSmtp.ZeusFrameworkSmtp.Send(String& error)zh-cn ZeusFrameworkSmtp.ZeusFrameworkSmtp.Send(字符串和错误)
en AssemblyZeusSMTP.AssemblyZeusSMTP.ZeusFW_EmailqueueUnit_SendOutError(SqlInt32 id_email, SqlString& sError)zh_cn AssemblyZeusSMTP.AssemblyZeusSMTP.ZeusFW_EmailqueueUnit_SendOutError(SqlInt32 id_email,SqlString&sError)
Here are some things to look at: 这里有一些事情要看:
Please use the Sql*
types instead of the native .NET types for input and output parameters for the SQLCLR public methods. 对于SQLCLR公共方法的输入和输出参数,请使用
Sql*
类型而不是本机.NET类型。 So the signature should be: 因此签名应为:
public static SqlInt32 CustomMethod(SqlInt32 id_email, out SqlString sError)
You can get the native values out of any of those types via the .Value
property that they all have (eg id_email.Value
). 您可以通过它们都具有的
.Value
属性(例如id_email.Value
)从任何这些类型中获取本机值。
You went through the trouble of passing back the status code, so capture it so you can see more of what is going on. 您遇到了传回状态代码的麻烦,因此请捕获它,以便您可以查看正在发生的事情。 In the C# code, assign a non-zero value to
mReturn
based on bresult
: 在C#代码中,根据
bresult
为mReturn
分配一个非零值:
if (bresult) { mReturn = 1; } else { mReturn = 2; }
And then change your T-SQL to be: 然后将您的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];
Looking at the posted code, it seems like the only ways to get an empty string for @sError
(is it really empty?) are: 查看发布的代码,似乎为
@sError
获取空字符串的唯一方法(它真的为空吗?)是:
email.Send()
is actually passing back a non-empty string of white-space and/or other non-printable characters. email.Send()
实际上是传回一个非空的空白字符串和/或其他不可打印的字符。 The T-SQL shown above has been adjusted to check for this. Other notes: 其他说明:
Result
instead of mReturn
, Result
instead of bResult
, and ErrorMessage
instead of sError
. Result
,而不是mReturn
, Result
不是bResult
和ErrorMessage
而不是sError
。 This goes for working in both C# and T-SQL. 1
from a Count
in a loop as that forces you to use <=
instead of just <
. Count
减去1
,因为这会迫使您使用<=
而不是<
。 Using j < ds.Tables[1].Rows.Count
is logically the same, one less (unnecessary) operation, and more readable :-). j < ds.Tables[1].Rows.Count
在逻辑上是相同的,减少了一次(不必要的)操作,并且更具可读性:-)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.