我有一个存储过程,我根据供应商要求集成两个系统来编写自定义XML。我想将每个记录写入一列以绕过sql列中的char限制。我包含了一个非常简单的SP版本。我在真正的SP中有600个字段。我在表中有4700条记录,我的XML在200行处理后被切断了。有没有办法在自己的列中返回Command action =“Upsert”invalidLookupBehavior =“Skip”和“/ Command”之间的所有内容? 我很难过。我为重复的帖子道歉.. 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开发人员。不幸的是我们有资源问题,所以我想我会尝试一下。我理解足够危险并正确提问。这要好得多。谢谢谢谢。在这个例子中只有少数字段(我有近600个字段和4700条记录每15分钟处理一次,因此需要这样做)。当我运行它时,XML仍然在第1200行被截断。有没有办法获取@myXML结果并根据数据源的行id解析为列?一排? SQL表中是否存在列号限制?这是我希望这张桌子看起来像的屏幕截图。 SQL Table concept
感谢您的帮助和耐心。 彭涅
我确定它是以两种方式截断的。 1-我使用xp_cmd_shell将文件保存到HD上的文件夹中 2-我已保存查询结果。
这是返回的文件行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。如何添加子节点==&gt; 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
答案 0 :(得分:2)
你正在做大量不必要的工作......
SELECT ... FOR XML
返回的结果(几乎)没有大小限制如果你这样,整个结果都在@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;