1

我正在尝试使用 Starfish ETL 从 Goldmine 5.5 迁移到 MCRM 2011。

问题是 Goldmine 数据库中有一个名为Mailbox的表,其中我需要迁移传入电子邮件的所有信息都存储在名为 rfc822(完整标题和正文消息)的单行中。即使在其他表中也没有发件人/收件人/等行。

我在我的 ETL 软件中将此查询用作 Origin 以从原始数据库 (Goldmine) 获取我需要的信息,但 Starfish 提供的默认地图在我的情况下不起作用。

SELECT  ch.*, c1.PHONE1, mb.RFC822 
FROM    CONTHIST ch 
        INNER JOIN CONTACT1 c1 
            ON ch.ACCOUNTNO=c1.ACCOUNTNO 
        INNER JOIN MAILBOX mb 
            ON ch.recid=mb.LINKRECID 
WHERE   ch.RECTYPE='MI'

之后,我可以映射目标 MCRM 电子邮件表并添加函数字段(vbscript、C#)。

大多数情况下,一旦作业完成,发件人/收件人将恢复为错误值(例如密件抄送字段中的用户)。

我想知道的是:

  • 如何提取存储在 rfc822 行中的 CC 和 BCC 字段
  • 有 HTML 和纯文本格式的电子邮件,唯一的区别方法是在这一行中查找。此外,Dynamics 不会以相同的方式存储它。
  • 如何使用 SQL 检索发件人和收件人?

我认为必须有一种方法可以使用 SQL 查询来完成这项工作。

4

1 回答 1

0

GoldMine 5.5(!哇) - 我的哀悼(事实上,机器人,你很幸运,因为在未来版本的 GoldMine rfc822 字段也是加密的)

我看到两个选项可以解决您的问题(都需要 SQL Server 2005 或更高版本):

  1. 与 SQLCLR 集成以能够使用正则表达式来解析 rfc822 字段
  2. 或使用 GoldMineAPI(如果您想从 SQL 使用 GoldMine API,则与 SQLCLR 集成)通过业务逻辑函数获取电子邮件

我有两个选项的一些例子:

例如,

使用 SQLCLR 解析 HTML 的示例

我写了一次它来解析 GoldMine 9.0 的 ContHist 注释

SQLCLR 函数 (C#)

[SqlFunction()]
public static SqlString RemoveHTML(SqlString html)
{
    if (!html.IsNull)
    {
        string remove_style = @"\<STYLE((\S|\ |\s)+?)\<\/STYLE\>";
        string remove_html = @"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>";

        string result = Regex.Replace(html.Value, remove_style, string.Empty, RegexOptions.IgnoreCase);
        result = Regex.Replace(result, remove_html, string.Empty, RegexOptions.IgnoreCase);

        return result;
    }
    else return new SqlString();
}

安装到数据库

USE YourDB
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO

ALTER DATABASE YourDB SET TRUSTWORTHY ON
----
CREATE ASSEMBLY GMSQLCLRAPI
FROM 'DRIVE:\Path\To\DLL\dll_name.dll'
with permission_set = UNSAFE;
--
CREATE FUNCTION RemoveHTML(@html NVARCHAR(MAX))
RETURNS NVARCHAR(MAX) WITH EXECUTE AS CALLER
AS EXTERNAL NAME GMSQLCLRAPI.[CLSQLCLR.GMSQLCLRAPI].RemoveHTML

用法

select dbo.RemoveHTML(rfc822) from Mailbox

使用这种方法,您可以将 SQLCLR 函数中的正则表达式替换为您自己的,它将为您解析收件人。

以及使用 GoldMine API 的示例

代码其实挺多的,我就提供几块

С# 包装函数调用 ReadMail GoldMine API 函数

public Dictionary<string, string> ReadMail(Dictionary<string, string> NVDictionary)
{
    const string failure = "Failure to read email\n";
    Int32 res;
    Dictionary<string, string> result = null;

    IntPtr nvc = import.GMW_NV_Create();
    if (nvc == null) throw (new CLGMAPIException(failure + "Unable to create name/value container"));
    try
    {
        foreach (KeyValuePair<string, string> kvp in NVDictionary)
        {
            import.GMW_NV_SetValue(nvc, kvp.Key, kvp.Value);
        }

        res = import.GMW_Execute("ReadMail", nvc);

        if (res > 0)
        {
            int count = import.GMW_NV_Count(nvc);
            result = new Dictionary<string, string>(count);
            IntPtr ptr;
            string name;

            for (int i = 0; i < count; i++)
            {
                ptr = import.GMW_NV_GetNameFromIndex(nvc, i);
                name = Marshal.PtrToStringAnsi(ptr);

                ptr = import.GMW_NV_GetValue(nvc, name, string.Empty);
                result[name] = Marshal.PtrToStringAnsi(ptr);
            }
        }
    }
    finally
    {
        import.GMW_NV_Delete(nvc);
    }

    switch (res)
    {
        case 0: throw (new CLGMAPIException(failure));
        case -1: throw (new CLGMAPIException(failure + "Message is private"));
        case -2: throw (new CLGMAPIException(failure + "Message not found, or cannot be loaded"));
        case -3: throw (new CLGMAPIException(failure + "Exception"));
        default:
            break;
    }

    return result;
}

包装器使用

public GoldMineEmails(GoldMineAPI api, DataTable mailbox)
{
    foreach (DataRow emailRow in mailbox.Rows)
    {
        var dict = new Dictionary<string, string>(3);
        dict["MboxRecID"] = emailRow["recid"].ToString();
        dict["History"] = "1";

        try
        {
            var res = api.ReadMail(dict);

            var email = new GoldMineEmail(res["To"], res["Cc"], res["Bcc"], res["Outgoing"])
            {
                body = res["Body"],
                From = res["From"],
                subject = res["Subject"],
                user = res["User"]
            };

            this.Add(email);
        }
        catch
        {
            throw;
            // error logging
        }
    }
}

我希望这有帮助。不要犹豫与我联系 - 我可以向您发送源代码示例

于 2013-05-09T07:16:09.503 回答