如何根据行数将 FULL XML 记录写入列

How to write a FULL XML record to column based on row count

我有一个存储过程,用于根据供应商集成两个系统的要求编写自定义 XML。我想将每条记录写入一列以绕过 sql 列中的字符限制。我包括我的 SP 的一个非常简单的版本。我在真正的 SP 中有 600 个字段。我在 table 中有 4700 条记录,我的 XML 在 200 行处理后被切断。有没有办法 return Command action="Upsert" invalidLookupBehavior="Skip" 和它们自己的列中的“/Command”之间的所有内容? 我很难过。我为重复 post.. TAB

道歉
USE [DEV]
GO
/****** Object:  StoredProcedure [dbo].[MASTER_TABLE_XML_PHASE_I]   ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[MASTER_TABLE_XML_PHASE_I_SIMPLE]
AS
declare
@xml nvarchar(max),
@metaEMPLOYEE nvarchar(max)

CREATE TABLE #MASTER_TABLE_IMPORT
(
[EMP_COMPANY_ID] [int] NOT NULL,
[EMP_LAST_NAME] [nvarchar](50) NULL,
[EMP_MIDDLE_NAME] [nvarchar](50) NULL,
[EMP_FIRST_NAME] [nvarchar](50) NULL,
[EMP_PREFIX] [nchar](6) NULL,
[EMP_PREFERRED_NAME] [nvarchar](50) NULL,
[EMP_FORMER_NAME] [nvarchar](50) NULL,
[EMP_SYSTEM_NUMBER] [nvarchar](100) NOT NULL,
[IMP_CREATE_DATE] [datetime] NULL,
[IMP_LAST_UPDATE_DATE] [datetime] NULL,
)

INSERT INTO #MASTER_TABLE_IMPORT
(
[EMP_COMPANY_ID] ,
[EMP_LAST_NAME] ,
[EMP_MIDDLE_NAME] ,
[EMP_FIRST_NAME],
[EMP_PREFIX] ,
[EMP_PREFERRED_NAME],
[EMP_FORMER_NAME] ,
[EMP_SYSTEM_NUMBER] ,
[IMP_CREATE_DATE],
[IMP_LAST_UPDATE_DATE]
)

SELECT
EMP_COMPANY_ID ,
EMP_LAST_NAME,
EMP_MIDDLE_NAME ,
EMP_FIRST_NAME,
EMP_PREFIX ,
EMP_PREFERRED_NAME,
EMP_FORMER_NAME ,
T1.EMP_SYSTEM_NUMBER,
IMP_CREATE_DATE,
IMP_LAST_UPDATE_DATE

FROM MASTER_TABLE_PHASE_I AS T1
INNER JOIN (SELECT EMP_SYSTEM_NUMBER ,MAX(IMP_CREATE_DATE) AS MaxDate
FROM MASTER_TABLE_PHASE_I
GROUP BY EMP_SYSTEM_NUMBER) AS T2
ON (T1.EMP_SYSTEM_NUMBER = T2.EMP_SYSTEM_NUMBER AND T1.IMP_CREATE_DATE =     T2.MaxDate)
/*OPEN XML FULL FILE TAGS*/
set @xml =
N'<DataChange><Commands>'
+ N'' + CHAR(10);

/*OPEN EMPLOYEE TABLE*/
/*OPEN EMPLOYEE FIELDS*/

select @metaEMPLOYEE =
CONVERT(nvarchar(max),
(
(select
/*OPEN XML UNIQUE RECORD TAGS*/
'<Command action="Upsert" invalidLookupBehavior="Skip"><Tables><Table     name="EMPLOYEE"><Fields>'+
'<Field name="COMPANY_ID" lookupValue="False">84</Field>',
'<Field name="LAST_NAME">' + EMP_LAST_NAME + '</Field>',
'<Field name="MIDDLE_NAME">' + EMP_MIDDLE_NAME + '</Field>',
'<Field name="FIRST_NAME">' + EMP_FIRST_NAME + '</Field>',
'<Field name="PREFIX" lookupValue="True">' + EMP_PREFIX + '</Field>',
'<Field name="PREFERRED_NAME">' + EMP_PREFERRED_NAME + '</Field>',
'<Field name="FORMER_NAME">' + EMP_FORMER_NAME + '</Field>',
'<Field name="SYSTEM_NUMBER" recordIdentifier="True">' + EMP_SYSTEM_NUMBER +         '</Field>',
/*CLOSE EMPLOYEE FIELDS*/
'</Fields>',
/*CLOSE EMPLOYEE TABLE*/
'</Table>',
/*CLOSE EMPLOYEE RECORD ALL TABLES*/
'</Tables>',
/*CLOSE XML COMMAND*/
/*CLOSE XML UNIQUE RECORD TAGS*/
'</Command>'
FROM #MASTER_TABLE_IMPORT
WHERE 1=1

FOR XML PATH(''),TYPE).value('(./text())[1]','NVARCHAR(MAX)')))
/*BUILD XML*/
/*CLOSING MASTER COMMAND*/
/*CLOSING MASTER DATA CHANGE*/

SET @xml = @xml + @metaEMPLOYEE +'</Commands></DataChange>'
SELECT @xml;

CREATE TABLE XMLDATA
(
xCol XML
) ;

INSERT INTO XMLDATA ( xCol )
SELECT @xml


DECLARE @Command VARCHAR(255)
DECLARE @Filename VARCHAR(100)

SELECT @Filename = 'C:\Client_XML\Data.dat'

SELECT @Command = 'bcp "select xCol from ' + DB_NAME()
+ '..XMLDATA" queryout '
+ @Filename + ' -w -T -S' + @@servername
EXECUTE master..xp_cmdshell @command
--WRITE THE XML TO A FILE

SELECT CONVERT(nVARCHAR(max),BulkColumn)
FROM OPENROWSET(BULK 'C:\Client_XML\Data.dat', SINGLE_BLOB) AS x

DROP TABLE XMLDATA

谢谢你 Shnugo。我不是 SQL 开发人员。不幸的是我们有资源问题,所以我想我会试一试。我了解足够危险并正确提出问题。这好多了。谢谢谢谢。此示例中只有少数字段(我每 15 分钟要处理近 600 个字段和 4700 条记录,因此需要这样做)。当我 运行 这个时,XML 仍然 t运行 位于第 1200 行。有没有办法获取 @myXML 结果并根据数据源的行ID?一排? SQL table 中是否有列数限制?这是我希望 table 看起来像的屏幕截图。 SQL Table concept

感谢您的帮助和耐心等待。 佩妮

我确定它是 t运行有两种方式。 1- 我正在使用 xp_cmd_shell 将文件保存到 HD 上的文件夹中 2- 我已保存查询结果。

这是 returned 文件第 1200 行中的最后一条记录

<Command action="Upsert" invalidLookupBehavior="Skip"><Tables><Table name="EMPLOYEE" /><Fields><Field name="COMPANY_ID" lookupValue="False">84</Field><Field name="LAST_NAME">Auditore</Field><Field name="MIDDLE_NAME" /><Field name="FIRST_NAME">Ezio</Field><Field name="PREFIX" loo

到此为止。 佩妮

嗨,Shnugo。如何将子节点 ==> ChildTables 添加到您的概念中?我只是不断收到错误。 ASSIGNMENT 语句中不允许使用 FOR XML 子句。

这就是 XML 结果的样子。我还在 ChildTables 中嵌套了 ChildTables。

<Command action="Upsert" invalidLookupBehavior="Skip"><Tables><Table name="EMPLOYEE"><Fields><Field name="COMPANY_ID" lookupValue="False">84</Field><Field name="LAST_NAME">Pinot</Field><Field name="FIRST_NAME">Gris</Field><Field name="PREFIX" lookupValue="True">Ms.</Field><Field name="SYSTEM_NUMBER" recordIdentifier="True">1603-XXXXX</Field><Field name="GENDER" lookupValue="True">Female</Field><Field name="MARITAL_STATUS" lookupValue="True">Married</Field><Field name="BIRTH_COUNTRY" lookupValue="True">Guatemala</Field><Field name="USER_ID_EMAIL">gris.pinot@me.com</Field></Fields><ChildTables><Table name="EMPLOYEE_CF"><Fields><Field name="CF_TEXT001">Gris</Field><Field name="CF_TEXT002">Pinot</Field><Field name="CF_TEXT003">Pinot</Field><Field name="CF_TEXT026">Family</Field><Field name="CF_TEXT027">No</Field><Field name="CF_NUMBER001">2</Field></Fields></Table><Table name="EMPLOYEE_PASSPORT"><Fields><Field name="ISSUE_COUNTRY" lookupValue="True">Guatemala</Field></Fields></Table><Table name="ASSIGNMENT"><Fields><Field name="NUMBER" recordIdentifier="True">1603-XXXXX</Field><Field name="FROM_COUNTRY" lookupValue="True">United Arab Emirates</Field><Field name="TO_COUNTRY" lookupValue="True">Malaysia</Field><Field name="TYPE" lookupValue="True">Long Term</Field><Field name="PHASE" lookupValue="True">New Assignment</Field><Field name="SCHEDULED_END_DATE">04/30/2019</Field><Field name="FROM_COMPANY_LEVEL1">From Level1</Field><Field name="FROM_COMPANY_LEVEL2">From Level2</Field><Field name="FROM_COMPANY_LEVEL3">From Level3</Field><Field name="FROM_COMPANY_LEVEL4">From Level4</Field><Field name="TO_COMPANY_LEVEL1">To Level1</Field><Field name="TO_COMPANY_LEVEL2">To Level2</Field><Field name="TO_COMPANY_LEVEL3">To Level3</Field><Field name="TO_COMPANY_LEVEL4">To Level4</Field></Fields><ChildTables><Table name="ASSIGNMENT_CF"><Fields><Field name="CF_TEXT002">No</Field><Field name="CF_TEXT005">1234567</Field><Field name="CF_TEXT009">1111111</Field><Field name="CF_TEXT010">2222222</Field><Field name="CF_DATE004">03/22/2016</Field><Field name="CF_DATE005">03/23/2016</Field></Fields></Table><Table name="ASSIGNMENT_EMPLOYEE_CONTACT"><Fields><Field name="LOCATION_TYPE" recordIdentifier="true">Current Address</Field><Field name="CONTACT_TYPE" recordIdentifier="true">Address</Field></Fields></Table><Table name="ASSIGNMENT_CONTACT"><Fields><Field name="TYPE" recordIdentifier="true">Manager</Field><Field name="NAME">Trinity</Field><Field name="EMAIL">trinity@me.com.com</Field><Field name="PHONE">5555555555</Field></Fields></Table><Table name="ASSIGNMENT_CONTACT"><Fields><Field name="TYPE" recordIdentifier="true">Home HR Contact</Field><Field name="NAME">Kim</Field><Field name="EMAIL">kim.@me.com</Field><Field name="PHONE">5555555551</Field></Fields></Table><Table name="ASSIGNMENT_CONTACT"><Fields><Field name="TYPE" recordIdentifier="true">HR Contact</Field><Field name="NAME">Pennie</Field><Field name="EMAIL">me@me.com</Field><Field name="PHONE">5555555552</Field></Fields></Table><Table name="ASSIGNMENT_MAILING_ADDRESS"><Fields><Field name="LOCATION_TYPE" recordIdentifier="true">Home Address</Field> </Fields></Table><Table name="POLICY"><Fields><Field name="NAME">424</Field></Fields></Table><Table name="UT_ACCOUNT_SPECIFIC_MISC_COMP_DATA"><Fields><Field name="HOME_BUSINESS_FUNCTION">Finance</Field><Field name="HOST_BUSINESS_FUNCTION">Finance</Field><Field name="EST_ASSIGNMENT_START_DATE">07/01/2016</Field></Fields></Table></ChildTables></Table></ChildTables></Table></Tables></Command>

感谢您的帮助。 佩妮 4/5 @Shnugo 这仍然没有解决,因为我无法使用@command。另一部分是我无法从结果集中写入 XML。这是习俗。结果集来自我不拥有的系统。尽管这一切都非常有帮助。我正在处理这些建议。我想投票,因为你反应灵敏,知识渊博。也许因为我太新了,所以无法投票。无论如何,我不清楚如何投票。 P

您正在做大量不必要的工作...

  • 看来你不需要临时工 table
  • 你应该永远不要通过字符串连接
  • 将你的XML构建为字符串
  • return由 SELECT ... FOR XML 编辑的结果(几乎)没有大小限制
  • 大小限制 - 在大多数情况下 - 绑定到中间步骤/转换/计算/等等,其中 return 类型不够大

如果你这样走,整个结果在@myXML中。 从那里你可以继续你喜欢...

DECLARE @myXML XML;

WITH CTE_instead_of_TempTable AS
(
    SELECT  EMP_COMPANY_ID ,
            EMP_LAST_NAME,
            EMP_MIDDLE_NAME ,
            EMP_FIRST_NAME,
            EMP_PREFIX ,
            EMP_PREFERRED_NAME,
            EMP_FORMER_NAME ,
            T1.EMP_SYSTEM_NUMBER,
            IMP_CREATE_DATE,
            IMP_LAST_UPDATE_DATE
    --This is the source you are using to fill your temp table. Cannot know, wheter it's correct or not
    --The two "FROM" lines are disturbing...
    FROM MASTER_TABLE_PHASE_I AS T1
    INNER JOIN (SELECT EMP_SYSTEM_NUMBER ,MAX(IMP_CREATE_DATE) AS MaxDate
    FROM MASTER_TABLE_PHASE_I
    GROUP BY EMP_SYSTEM_NUMBER) AS T2
    ON (T1.EMP_SYSTEM_NUMBER = T2.EMP_SYSTEM_NUMBER AND T1.IMP_CREATE_DATE =     T2.MaxDate)
)
SELECT @myXML=
(
    SELECT
    (
     SELECT
         'Upsert'               AS [@action]
        ,'Skip'                 AS [@invalidLookupBehavior]
        ,(
            SELECT 
                'EMPLOYEE'             AS [Table/@name]
               ,(
                    SELECT
                         'COMPANY_ID'           AS [Field/@name]
                        ,'False'                AS [Field/@lookupValue]
                        ,84                     AS [Field]
                        ,''
                        ,'LAST_NAME'            AS [Field/@name]
                        ,EMP_LAST_NAME          AS [Field]
                        ,''
                        ,'MIDDLE_NAME'          AS [Field/@name]
                        ,EMP_MIDDLE_NAME        AS [Field]
                        ,''
                        ,'FIRST_NAME'           AS [Field/@name]
                        ,EMP_FIRST_NAME         AS [Field]
                        ,''
                        ,'PREFIX'               AS [Field/@name]
                        ,'True'                 AS [Field/@lookupValue]
                        ,EMP_PREFIX             AS [Field]
                        ,''
                        ,'PREFERRED_NAME'       AS [Field/@name]
                        ,EMP_PREFERRED_NAME     AS [Field]
                        ,''
                        ,'FORMER_NAME'          AS [Field/@name]
                        ,EMP_FORMER_NAME        AS [Field]
                        ,''
                        ,'SYSTEM_NUMBER'        AS [Field/@name]
                        ,'True'                 AS [Field/@recordIdentifier]
                        ,EMP_SYSTEM_NUMBER      AS [Field]
                    FOR XML PATH(''),TYPE
                ) AS [Fields]
            FOR XML PATH('Tables'),TYPE
          ) 
        FROM CTE_instead_of_TempTable
        FOR XML PATH('Command'),TYPE
      )
    FOR XML PATH('Commands'),ROOT('DataChange'),TYPE
)

SELECT @myXML;