【问题标题】:Send email to DISTINCT email发送电子邮件到 DISTINCT 电子邮件
【发布时间】:2009-09-23 11:10:19
【问题描述】:

我有一个经典的 ASP 页面,让用户可以搜索属性和一个结果页面,然后通过电子邮件向具有匹配属性的房地产代理发送电子邮件,让他们知道有租户对他们的属性感兴趣。

某些代理可能拥有超过 1 个属性,在这种情况下,代理只需要收到 1 封电子邮件,而不是为他们拥有的每个属性接收一封电子邮件。目前我的代码正在执行后者,我需要它只向每个代理发送 1 封电子邮件。

在下面的代码中,我有 2 个记录集; rspropertyresults 显示所有匹配的属性,然后我有 rsemailagents 用于收集代理的电子邮件地址并向他们发送电子邮件。

我想知道是否有人能够看到我如何修改 rsemailagents 的 sql 查询以向每个代理发送 1 封电子邮件?

<%
[...]
rsemailagents.Source = "SELECT *"
rsemailagents.Source = rsemailagents.Source& "FROM    ("
rsemailagents.Source = rsemailagents.Source& "        SELECT  ContentID"
rsemailagents.Source = rsemailagents.Source& "        FROM    ("
rsemailagents.Source = rsemailagents.Source& "                SELECT  ContentID"
rsemailagents.Source = rsemailagents.Source& "                FROM    VWTenantPropertiesResults"
rsemailagents.Source = rsemailagents.Source& "                WHERE   ContentStreet = '" & Replace(rsemailagents__varReqStreet, "'", "''") & "'"
rsemailagents.Source = rsemailagents.Source& "                UNION ALL"
rsemailagents.Source = rsemailagents.Source& "                SELECT  ContentID"
rsemailagents.Source = rsemailagents.Source& "                FROM    VWTenantPropertiesResults"
rsemailagents.Source = rsemailagents.Source& "                WHERE   ContentTown = '" & Replace(rsemailagents__varReqTown, "'", "''") & "'"
rsemailagents.Source = rsemailagents.Source& "                UNION ALL"
rsemailagents.Source = rsemailagents.Source& "                SELECT  ContentID"
rsemailagents.Source = rsemailagents.Source& "                FROM    VWTenantPropertiesResults"
rsemailagents.Source = rsemailagents.Source& "                WHERE   ContentTrimmedPostCode LIKE '" & Replace(varPostcode, "'", "''") & "%'"
rsemailagents.Source = rsemailagents.Source& "                ) qi"
rsemailagents.Source = rsemailagents.Source& "        GROUP BY"
rsemailagents.Source = rsemailagents.Source& "                ContentID"
rsemailagents.Source = rsemailagents.Source& "        HAVING  COUNT(*) >= 2"
rsemailagents.Source = rsemailagents.Source& "        ) q "
rsemailagents.Source = rsemailagents.Source& "JOIN    VWTenantPropertiesResults r "
rsemailagents.Source = rsemailagents.Source& "ON      r.ContentID = q.ContentID "
rsemailagents.Source = rsemailagents.Source& "WHERE   ContentBedrooms BETWEEN " & Replace(rsemailagents__varBedroomsNoMin, "'", "''") & " "
rsemailagents.Source = rsemailagents.Source& "AND     " & Replace(rsemailagents__varBedroomsNoMax, "'", "''") & " "
rsemailagents.Source = rsemailagents.Source& "AND     ContentPrice BETWEEN " & Replace(rsemailagents__varPriceMin, "'", "''") & " "
rsemailagents.Source = rsemailagents.Source& "AND     " & Replace(rsemailagents__varPriceMax, "'", "''") & " " & varSQL & " "
rsemailagents.Source = rsemailagents.Source& "ORDER BY"
rsemailagents.Source = rsemailagents.Source& "        ContentPrice " & Replace(rsemailagents__varSortWay, "'", "''") & " "
rsemailagents.Source = rsemailagents.Source& "GROUP BY CustomerEmail"

[...]
%>

在我的电子邮件代码中,我将 objMail.To 设置如下;

objMail.To = (rsemailagents.Fields.Item("CustomerEmail").Value)

这是 VWTenantPropertiesResults 代码;

SELECT     dbo.VWResidentialLettings.ContentID, dbo.VWResidentialLettings.ContentTitle, dbo.VWResidentialLettings.ContentBriefText, 
                      dbo.VWResidentialLettings.ContentDetails, dbo.VWResidentialLettings.ContentHouseNo, dbo.VWResidentialLettings.ContentStreet, 
                      dbo.VWResidentialLettings.ContentStreet2, dbo.VWResidentialLettings.ContentTown, dbo.VWResidentialLettings.ContentArea, 
                      dbo.VWResidentialLettings.ContentCounty, dbo.VWResidentialLettings.ContentPostCode, dbo.VWResidentialLettings.ContentReference, 
                      dbo.VWResidentialLettings.ContentPrice, dbo.VWResidentialLettings.ContentPricePeriod, dbo.VWResidentialLettings.ContentPriceText, 
                      dbo.VWResidentialLettings.ContentPropertyType, dbo.VWResidentialLettings.PropertyTypeTitle, dbo.VWResidentialLettings.ContentPropertyListType, 
                      dbo.VWResidentialLettings.PropertyListTypeTitle, dbo.VWResidentialLettings.PricePeriodTitle, dbo.VWResidentialLettings.BedRoomNoTitle, 
                      dbo.VWResidentialLettings.ContentBedRooms, dbo.VWResidentialLettings.ContentFurnishing, dbo.VWResidentialLettings.FurnishTypeTitle, 
                      dbo.VWPropertyAgentsActiveSubscriptions.CustomerID, dbo.VWPropertyAgentsActiveSubscriptions.CustomerName, 
                      dbo.VWPropertyAgentsActiveSubscriptions.CustomerBusiness, dbo.VWPropertyAgentsActiveSubscriptions.CustomerAddress1, 
                      dbo.VWPropertyAgentsActiveSubscriptions.CustomerAddress2, dbo.VWPropertyAgentsActiveSubscriptions.CustomerCity, 
                      dbo.VWPropertyAgentsActiveSubscriptions.CustomerArea, dbo.VWPropertyAgentsActiveSubscriptions.CustomerRegion, 
                      dbo.VWPropertyAgentsActiveSubscriptions.CustomerPostalCode, dbo.VWPropertyAgentsActiveSubscriptions.CustomerPhone, 
                      dbo.VWPropertyAgentsActiveSubscriptions.CustomerFax, dbo.VWPropertyAgentsActiveSubscriptions.CustomerURL, 
                      dbo.VWPropertyAgentsActiveSubscriptions.CustomerEmail, dbo.VWResidentialLettings.CountyTitle, dbo.VWResidentialLettings.ContentCreated, 
                      dbo.VWResidentialLettings.ContentUpdated, dbo.VWResidentialLettings.ContentStatus, dbo.VWPropertyImagesList.DocumentFile, 
                      dbo.VWPropertyImagesList.DocumentTitle, dbo.VWResidentialLettings.ContentTrimmedPostCode, dbo.VWPropertyImagesList.ContentStatusTitle
FROM         dbo.VWResidentialLettings INNER JOIN
                      dbo.VWPropertyAgentsActiveSubscriptions ON 
                      dbo.VWResidentialLettings.ContentParentID = dbo.VWPropertyAgentsActiveSubscriptions.CustomerID LEFT OUTER JOIN
                      dbo.VWPropertyImagesList ON dbo.VWResidentialLettings.ContentID = dbo.VWPropertyImagesList.ContentID
WHERE     (dbo.VWResidentialLettings.ContentStatus = 2)

当我在数据库中运行此查询时,它只返回一个 CustomerEmail 列,没有其他内容;

SELECT DISTINCT CustomerEmail
FROM    (
    SELECT  ContentID
    FROM    (
                SELECT  ContentID
                FROM    VWTenantPropertiesResults
                WHERE   ContentStreet = 'Hull'
                UNION ALL
                SELECT  ContentID
                FROM    VWTenantPropertiesResults
                WHERE   ContentTown = ''
                UNION ALL
                SELECT  ContentID
                FROM    VWTenantPropertiesResults
                WHERE   ContentTrimmedPostCode LIKE 'HU7'
                ) qi
        GROUP BY
                ContentID
        HAVING  COUNT(*) >= 2
        ) q
JOIN    VWTenantPropertiesResults r
ON      r.ContentID = q.ContentID
WHERE   ContentBedrooms BETWEEN 1 AND 10 AND ContentPrice BETWEEN 1 AND 10

【问题讨论】:

  • 也许您应该只发布 SQL 语句本身而不是它周围的代码。你不能直接将 SQL 踢到存储过程中,或者使用 DatabaseSpy 之类的东西来测试它吗?
  • 能否请您发布您的表格结构?
  • 能否请您输出并发布给出错误的整个查询?我的意思是查询本身,而不是生成它的代码。
  • @Quassnoi - 我已经发布了我在数据库中完成的示例查询。希望这就是你所追求的?
  • 能否在 Management Studio 中运行此查询并查看它是否运行?

标签: sql asp-classic


【解决方案1】:

将您的查询放入此查询的IN 子句

SELECT  email
FROM    agents
WHERE   id IN
        (
        SELECT  agentID
        FROM    …
        )

这将只选择每个代理一次。

【讨论】:

  • @Quassnoi 会是这样吗? SELECT CustomerEmail FROM VWTenantPropertiesResults WHERE CustomerID IN ( SELECT ContentID FROM ( SELECT ContentID" FROM VWTenantPropertiesResults" WHERE Con​​tentStreet = '" & Replace(rsemailagents__varReqStreet, "'", "''") & "'" UNION ALL" SELECT ContentID" FROM VWTenantPropertiesResults" WHERE Con​​tentTown = '" & Replace(rsemailagents__varReqTown, "'", "''") & "'" UNION ALL" SELECT ContentID" FROM VWTenantPropertiesResults" [...]
  • 如果您的电子邮件包含在VWTenantPropertiesResults 中,您可以只在查询中使用SELECT DISTINCT CustomerEmail。能否请您发布您的表格布局?
  • 我已经发布了上面用于获取结果的视图。我尝试使用 SELECT DISTINCT CustomerEmail 但收到以下错误; Microsoft OLE DB Provider for SQL Server 错误“80040e14”关键字“SELECT”附近的语法不正确。第 541 行
【解决方案2】:

您使用别名“q”的子查询有一个字段,即 ContentID。除非您有非常奇怪的命名约定,否则这不是电子邮件地址。因此,您告诉它“选择 CustomerEmail From(没有名为 CustomerEmail 的字段的类似表的对象)”。这不可能工作,我很惊讶它返回的不是错误消息。

尝试查看“IN”子句或“EXISTS”子句。

【讨论】:

    【解决方案3】:

    好的...

    尝试创建一个子查询,将所有属性组合在一行中。

    您可以通过这样的查询创建组来做到这一点:

    select 
        contentID , count(*) hits 
    from 
        VWTenantPropertiesResults 
    where 
        propertyValue in ('A','B','C')
    group by 
        contentID 
    

    此外,您很容易受到 SQL 注入攻击,因为您在创建 SQL 时没有正确转义它。在这里考虑一个参数化查询,或者一个存储过程。

    您还有一种非常复杂的方式来创建您的查询。您在 10 多个步骤中构建了一个字符串,并将其分配给该属性。考虑在这里使用字符串生成器,因为字符串是不可变的,这可能会导致性能问题(尤其是在循环中使用类似的东西时......如果您需要超过 5 个连接,那么请考虑使用字符串生成器)

    【讨论】:

      猜你喜欢
      • 2012-07-02
      • 1970-01-01
      • 2016-11-30
      • 2011-09-16
      • 1970-01-01
      • 2014-05-30
      • 1970-01-01
      • 2012-04-09
      • 1970-01-01
      相关资源
      最近更新 更多