【问题标题】:Update record in SQL after data export to CSV数据导出到 CSV 后更新 SQL 中的记录
【发布时间】:2013-03-21 23:26:45
【问题描述】:

我对 SSIS 还是很陌生,而且总体上在 SQL 方面走得更远。我创建了一个数据流任务,它从表中提取与 UNION ALL 脚本匹配的记录,并将它们转储到服务器上的 .CSV 文件中。然后我添加了一个 FTP 任务,将文件上传到收件人,以便他们最终处理。转储数据的条件之一是表中的 TransDate 字段为空白且 StartDate 字段等于今天。因为有 4 个 StartDates 和 4 个 TransDates,所以我使用 UNION All 并根据 4 组数据中的哪一组分配一个“行号”。我缺少的是一种验证转储到 CSV 的记录然后设置对应于该行的 TransDate 的方法。

SELECT
    CallLog.CallID as Ticket
    , 1 as Line
    , CallLog.CustID as Store#
    , AcctNum as SoldTo
    , CAST(BillStart01 as DATE) as BillStart
    , Cast(BillEnd01  as DATE) as BillEnd
    , CostSheet01 as BillAmount
    , SKU01 as SKU
    , Term01 as Terms
    , CAST(EffDate01 as DATE) as EffStart
    , CAST(EffDate02 as DATE) as EffEnd
FROM
    CallLog, Detail, Subset
WHERE
    (CallLog.CallID=Detail.CallID and CallLog.CallID=Subset.CallID) 
AND CallType='Contract' 
    AND TransDate01 = ''
    AND Cast(SentOps as Date) = CONVERT(date,GETDATE()) 
    AND Month(RcvDate01) <= Month(GETDATE()) 
    AND YEAR(RcvDate01) = YEAR(GetDate())

UNION ALL

SELECT CallLog.CallID as Ticket
    , 2 as Line
    , CallLog.CustID as Store#
    , AcctNum as SoldTo
    , CAST(BillStart 02 as DATE) as BillStart
    , Cast(BillEnd02 as DATE) as BillEnd
    , CostSheet02 as BillAmount
    , SKU02 as SKU
    , Term02 as Terms
    , CAST(EffDate01 as DATE) as EffStart
    , CAST(EffDate02 as DATE) as EffEnd
FROM
    CallLog, Detail, Subset
WHERE
    (CallLog.CallID=Detail.CallID and CallLog.CallID=Subset.CallID) 
AND CallType='Contract' 
    AND TransDate02 = ''
    AND Cast(SentOps as Date) = CONVERT(date,GETDATE())
    AND Month(RcvDate02) <= Month(GETDATE()) 
    AND YEAR(RcvDate02)=YEAR(GetDate())

UNION ALL

SELECT
    CallLog.CallID as Ticket
    , 3 as Line
    , CallLog.CustID as Store#
    , AcctNum as SoldTo
    , CAST(BillStart 03 as DATE) as BillStart
    , Cast(BillEnd03 as DATE) as BillEnd
    , CostSheet03 as BillAmount
    , SKU03 as SKU
    , Term03 as Terms
    , CAST(EffDate01 as DATE) as EffStart
    , CAST(EffDate02 as DATE) as EffEnd
FROM 
    CallLog, Detail, Subset
WHERE
    (CallLog.CallID=Detail.CallID and CallLog.CallID=Subset.CallID)
    AND CallType='Contract' 
    AND TransDate03 = ''
    AND Cast(SentOps as Date) = CONVERT(date,GETDATE())
    AND Month(RcvDate03) <= Month(GETDATE())
    AND YEAR(RcvDate03) = YEAR(GetDate())

UNION ALL

SELECT
    CallLog.CallID as Ticket
    , 4 as Line
    , CallLog.CustID as Store#
    , AcctNum as SoldTo
    , CAST(BillStart 04 as DATE) as BillStart
    , Cast(BillEnd04 as DATE) as BillEnd
    , CostSheet04 as BillAmount
    , SKU04 as SKU
    , Term04 as Terms
    , CAST(EffDate01 as DATE) as EffStart
    , CAST(EffDate02 as DATE) as EffEnd
FROM
    CallLog, Detail, Subset
WHERE
    (CallLog.CallID=Detail.CallID AND CallLog.CallID=Subset.CallID) 
AND CallType='Contract' 
    AND TransDate04 = ''
    AND Cast(SentOps as Date) = CONVERT(date,GETDATE()) 
    AND Month(RcvDate04)<=Month(GETDATE()) 
    AND YEAR(RcvDate04)=YEAR(GetDate())
Order BY Ticket, Line

感谢任何帮助/指导。

谢谢,

杰夫

【问题讨论】:

    标签: ssis sql-server-2008-r2


    【解决方案1】:

    Jeff,您似乎需要将这 4 个选择语句中的每一个都保存在单独的数据源中 - 所以 4 个 OLEDB 数据源。这似乎是您解决方案的关键。

    然后在每个数据源之后,使用条件拆分来确定该行是否应包含在输出中。因此,每个来源都有 4 个条件拆分。

    您还需要在条件拆分后立即进行派生列转换(如果已满足条件)来设置 TransDate。

    最终,使用 Union All 转换将它们合并在一起,并将 union all 的输出放到您的 csv 文件中。

    【讨论】:

    • Anoop,因为我还是新手,这对我来说没有多大意义。带有 UNION ALL 的 select 语句正在提取我需要的记录,我只需要返回并更新 TransDate 以显示记录已被提取。如果 Ticket = 123 和 line = 1 出现在 csv 中,我认为应该很容易说,转到 SQL 表中的记录 123 并设置 TransDate01 = 今天,然后处理为 csv 提取的所有记录文件。我可以使用 UPDATE 脚本在 SQL 中的表之间执行此操作,我只是不知道如何在 SSIS 中执行任何操作。
    • 我能说你有两件事要做 - 创建一个 csv 文件,然后更新一个用作源的表吗?如果是,那么您是否可以不使用 SQL 识别和标记这些记录(如您所提到的)而只使用 SSIS 创建 CSV?这将为您节省往返行程。
    • 如果我没看错,你是说我应该首先更新 TransDate 字段,然后拉取具有 TransDate 的记录?不幸的是,这个过程会在一天中运行多次,可能每 15 分钟一次,而且我不想多次提取相同的记录,因为这是针对计费应用程序的。我现在想的是在 SQL 中将记录转储到临时表中的临时步骤,使用它来验证记录以更新 TransDate,然后将内容或临时表转储到 csv,然后清除临时表表。
    • 我已经决定我过于复杂了,只需将其分解为如下步骤:1)查询数据并转储到 SQL 中的临时表; 2) 运行 SQL UPDATE 脚本,根据原始表和临时表的比较来设置 TransDate; 3) 将临时表转储为 CSV; 4) 运行 SQL DELETE 脚本来清除临时表。它可能不是最优雅或最干净的方式,但我会得到我需要的功能。感谢您为帮助我所做的努力。
    • 太棒了!出于好奇,有几个问题... 1. 您是否在原始表所在的服务器上创建了临时表? 2. 您是否使用 Merge 命令来比较 temp 和 original?合并非常有效。感谢您的更新 - 非常专业!
    【解决方案2】:

    管理导出批次的更强大的方法:

    1. 通过使用标记日期(例如 2099-01-01)更新所有空白转换日期来标记要导出的记录(在所有四个表中)。这会识别并“冻结”您将要导出的那批记录。

    2. 现在只导出和传输日期为 2099-01-01 的记录

    3. 导出和 FTP 过程无误完成后,将标记为 Transdate 的记录更新为今天的日期

    4. 如果该过程没有发生错误,请将 2099-01-01 日期设置回空白。

    此过程允许您隔离要导出的记录。如果您不先标记它们,那么当您仍在导出较早的集合时,可能会到达新的(空白)记录,然后它们会被错误地标记为“已导出”。

    【讨论】:

    • 这听起来也很好用。至此,我已经基本完成了项目的构建和测试,但我会尝试遵循这一点,看看是否有任何性能改进。谢谢。
    • 不会有任何性能提升,只是可靠性提升。祝你好运。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-05
    相关资源
    最近更新 更多