为SQL Server数据库中的每一行创建平面文件的最佳方法是什么?

时间:2018-03-19 14:01:25

标签: sql-server xml ssis

我刚刚写了一篇允许我根据查询创建XML文件的脚本。我修复了它,现在可以使用下面看到的脚本为给定记录创建XML字符串(请注意最外层查询中的'where'子句:

declare @body nvarchar(max) =
N'<?xml version="1.0" encoding="utf-8"?><Mapi 
destination_reference="ABC06EMP" name="WorkOrder" source_reference="ABC999" 
xmlns="http://www.company.com/Mapi/WorkOrder" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' +
cast((
select 'ABC999' as SourceTradingPartner,
     'ABC06EMP' as DestinationTradingPartner,
     right('                    ' + 'E_' + cast(WorkOrderHeader.EmpNumber as varchar), 20) as WorkOrder,
     WorkOrderHeader.Name as WorkOrderDescription,
     'OPR' as ResponsiblePersonID,
     'USA' as DivisionID,
     'A' as SynchIndicatorID
    , (
    select '0001' as WorkOrderLineReference,
             'CONSIGN' as Item,
             '2018-03-09' as RequiredManufacturingStartDate,
             '2018-03-09' as OpenDate,
             '2018-03-09' as DueDate,
             '1' as OrderQty,
             'W' as RoutingUsedFlag,
             'I' as BillOfMaterialUsedFlag,
             'B' as ScheduleID,
             '3' as QAStatusID,
             'CNSG' as AccountingGroupCode,
             'R' as StateCode,
             '134800' as DueTime,
             '144846' as OpenTime,
             '134800' as RequiredManufacturingStartTime,
             '2' as InventoryStatus,
             'A' as SynchIndicatorID,
             'Y' as SubstitutePriorityMethod
        , (
        select 'A' as SynchIndicatorID,
                 '10' as Increment
            ,(
            select 'A' as SynchIndicatorID,
                     '  10' as Operation,
                     'CONSIGN' as [Function],
                     'I' AS OperationType,
                     rtrim(isnull(WorkOrderRouting.WorkCenter, '')) as WorkCenter
                , (
                select 'A' as SynchIndicatorID,
                         right('    ' + cast(row_number() over (partition by WorkOrderRoutingTool.Employee
                                                                             order by WorkOrderRoutingTool.id desc, WorkOrderRoutingTool.PartNumber)
                                                    as varchar), 4) as ToolSeq,
                         WorkOrderRoutingTool.PartNumber as ToolID,
                         cast(WorkOrderRoutingTool.Qty as varchar) as ToolQuantity
                from ZLS_CONSIGN WorkOrderRoutingTool with (nolock)
                where WorkOrderRoutingTool.Employee = WorkOrderHeader.OID
                for xml auto, elements, type
                )
            from Employees WorkOrderRouting with (nolock)
            where WorkOrderRouting.OID = WorkOrderHeader.OID
            for xml auto, elements, type
            )
            ,(
            select 'A' as SynchIndicatorID
            from Employees WorkOrderRoutingAddendum with (nolock)
            where WorkOrderRoutingAddendum.OID = WorkOrderHeader.OID
            for xml auto, elements, type
            )
        from Employees WorkOrderRoutingHeader with (nolock)
        where WorkOrderRoutingHeader.OID = WorkOrderHeader.OID
        for xml auto, elements, type
        )
    from Employees WorkOrderLine with (nolock)
    where WorkOrderLine.OID = WorkOrderHeader.OID
    for xml auto, elements, type
    )
    ,(
    select 'A' as SynchIndicatorID,
             '4' as PlanningStatus,
             '2' as ManufacturingStatus
    from Employees WorkOrderLineAddendum with (nolock)
    where WorkOrderLineAddendum.OID = WorkOrderHeader.OID
    for xml auto, elements, type
    )
from Employees WorkOrderHeader with (nolock)
where WorkOrderHeader.EmpNumber = 10171
order by WorkOrderHeader.EmpNumber
for xml auto, elements, type
) as nvarchar(max)) +
N'</Mapi>';
select @body as COL_XML;

在SSMS中使用此查询可以正常工作,我可以使用正确的标记获取XML代码。我已经使用它并将其保存为XML文件,对其进行测试,我的系统加载它没有任何问题。

现在,我需要我的进程为我创建XML文件。为此,我正在使用Visual Studio的Integration Services项目:

!(https://ibb.co/eBBpSx

正如您所看到的,OLE DB Source块具有我上面使用的SQL脚本,然后我将输出转换为DT_TEXT并使用代码页65001(UTF-8),最后使用平面文件目标。但是最后一个有一个静态文件名,我需要根据表中的每个记录创建文件。

所以我必须删除脚本中的'where'子句,让它为所有员工运行,并为每个员工记录创建一个XML文件。不确定我是否仍然可以使用SSIS包执行此操作。我正在测试bcp SQL命令的使用,但我在SQL Server v2008上,我正在阅读它在创建特定格式的文件时有一些限制。

如何为每个员工记录创建多个XML文件?

感谢所有帮助。感谢。

更新1:这是我一直试图与bcp一起使用的代码,但它给了我各种错误。

declare @fileName varchar(max)
declare @sqlStr varchar(max)
declare @sqlCmd varchar(8000)

set @fileName = 'C:\Temp\saved.xml'

SET @sqlStr = 'declare @body nvarchar(max) = ' +
              '''<?xml version="1.0" encoding="utf-8"?><Mapi destination_reference="ABC06EMP" name="WorkOrder" source_reference="ABC999" xmlns="http://www.company.com/gapi/WorkOrder" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">''' +
              'cast((' +
              'select ''ABC999'' as SourceTradingPartner, ' +
              '''ABC06EMP'' as DestinationTradingPartner, ' +
              'right(''                    '' + ''E_'' + cast(WorkOrderHeader.EmpNumber as varchar), 20) as WorkOrder, ' +
              'WorkOrderHeader.Name as WorkOrderDescription, ' +
              '''OPR'' as ResponsiblePersonID, ' +
              '''USA'' as DivisionID, ' +
              '''A'' as SynchIndicatorID' +
              ', (' +
              'select ''0001'' as WorkOrderLineReference, ' +
              '''CONSIGN'' as Item, ' +
              '''2018-03-09'' as RequiredManufacturingStartDate, ' +
              '''2018-03-09'' as OpenDate, ' +
              '''2018-03-09'' as DueDate, ' +
              '''1'' as OrderQty, ' +
              '''W'' as RoutingUsedFlag, ' +
              '''I'' as BillOfMaterialUsedFlag, ' +
              '''B'' as ScheduleID, ' +
              '''3'' as QAStatusID, ' +
              '''CNSG'' as AccountingGroupCode, ' +
              '''R'' as StateCode, ' +
              '''134800'' as DueTime, ' +
              '''144846'' as OpenTime, ' +
              '''134800'' as RequiredManufacturingStartTime, ' +
              '''2'' as InventoryStatus, ' +
              '''A'' as SynchIndicatorID, ' +
              '''Y'' as SubstitutePriorityMethod' +
              ', (' +
              'select ''A'' as SynchIndicatorID, ' +
              '''10'' as Increment' +
              ',(' +
              'select ''A'' as SynchIndicatorID, ' +
              '''  10'' as Operation, ' +
              '''CONSIGN'' as [Function], ' +
              '''I'' AS OperationType, ' +
              'rtrim(isnull(WorkOrderRouting.WorkCenter, '''')) as WorkCenter' +
              ', (' +
              'select ''A'' as SynchIndicatorID, ' +
              'right(''    '' + cast(row_number() over (partition by WorkOrderRoutingTool.Employee ' +
              'order by WorkOrderRoutingTool.id desc, WorkOrderRoutingTool.PartNumber) ' +
              'as varchar), 4) as ToolSeq, ' +
              'WorkOrderRoutingTool.PartNumber as ToolID, ' +
              'cast(WorkOrderRoutingTool.Qty as varchar) as ToolQuantity ' +
              'from ZLS_CONSIGNACION WorkOrderRoutingTool with (nolock) ' +
              'where WorkOrderRoutingTool.Employee = WorkOrderHeader.OID ' +
              'for xml auto, elements, type' +
              ') ' +
              'from Employees WorkOrderRouting with (nolock) '+
              'where WorkOrderRouting.OID = WorkOrderHeader.OID ' +
              'for xml auto, elements, type' +
              ')' +
              ', (' +
              'select ''A'' as SynchIndicatorID ' +
              'from Employees WorkOrderRoutingAddendum with (nolock) ' +
              'where WorkOrderRoutingAddendum.OID = WorkOrderHeader.OID ' +
              'for xml auto, elements, type' +
              ') ' +
              'from Employees WorkOrderRoutingHeader with (nolock) ' +
              'where WorkOrderRoutingHeader.OID = WorkOrderHeader.OID ' +
              'for xml auto, elements, type' +
              ') ' +
              'from Employees WorkOrderLine with (nolock) ' +
              'where WorkOrderLine.OID = WorkOrderHeader.OID ' +
              'for xml auto, elements, type' +
              ')' +
              ', (' +
              'select ''A'' as SynchIndicatorID, ' +
              '''4'' as PlanningStatus, ' +
              '''2'' as ManufacturingStatus ' +
              'from Employees WorkOrderLineAddendum with (nolock) ' +
              'where WorkOrderLineAddendum.OID = WorkOrderHeader.OID ' +
              'for xml auto, elements, type' +
              ') ' +
              'from Employees WorkOrderHeader with (nolock) ' +
              'where WorkOrderHeader.EmpNumber = 10171 ' +
              'order by WorkOrderHeader.EmpNumber ' +
              'for xml auto, elements, type' +
              ') as nvarchar(max)) + ' +
              '''</Mapi>''; ' +
              'select @body as COL_XML;'

set @sqlCmd = 'bcp "' + @sqlStr + '" queryout ' + @fileName + ' -w -T'

exec xp_cmdshell @sqlCmd

更新2:在为每条记录创建单个文件时,我正在尝试遵循这些说明: https://www.red-gate.com/simple-talk/sql/ssis/implementing-foreach-looping-logic-in-ssis/

但是当我尝试使用这段代码时:

select 'SHV999' as SourceTradingPartner,
     'SHV06EMP' as DestinationTradingPartner,
     right('                    ' + 'E_' + cast(t.EmpNumber as varchar), 20) as WorkOrder,
...
from Employees t with (nolock)
where t.EmpNumber = ?
order by t.EmpNumber
for xml path('WorkOrderHeader'), type

我收到错误(请注意我已经为参数替换了静态旧值10171?): '有一个没有名称的数据源列

所以我尝试按如下方式命名XML列:

select (
select 'SHV999' as SourceTradingPartner,
     'SHV06EMP' as DestinationTradingPartner,
     right('                    ' + 'E_' + cast(t.EmpNumber as varchar), 20) as WorkOrder,
...
from Employees t with (nolock)
where t.EmpNumber = ?
order by t.EmpNumber
for xml path('WorkOrderHeader'), type
) as COL_XML

但现在我得到了一个不同的错误: “语法错误,权限违规或其他非特定错误”。

我找不到通过尝试在SQL查询中添加参数来实现此功能的方法,并且同时为该列命名。

任何想法都会受到欢迎。感谢。

0 个答案:

没有答案