SQL Server 中的 XML 列比较
Posted
技术标签:
【中文标题】SQL Server 中的 XML 列比较【英文标题】:XML columns compare in SQL Server 【发布时间】:2015-07-14 05:04:48 【问题描述】:我有 3 列:
-
[旧内容] [xml] NULL
[新内容] [xml] NULL
[旧内容] [xml] NULL
我想比较两列中的数据。我想将结果写入第三列([OldContent]
)
我如何在 SQL Server 中做到这一点?
[OldContent] [xml] NULL,在
价值
<row GUEST_ID="13" GUEST_NAME="VEDAT" GUEST_SURNAME="PALA" ADRESS="IZMIR" />
[NewContent] [xml] NULL,在值中
<row GUEST_ID="13" GUEST_NAME="VEDAT35" GUEST_SURNAME="PALA" ADRESS="IZMIR" CITY="DR" CITY_CODE="35" />
我想在里面写值。
[UpdateContent] [xml] NULL
<row GUEST_NAME="VEDAT35 CITY="DR" CITY_CODE="35" />
我需要一个比较 XML 列值的过程。
【问题讨论】:
获取xml数据并使用x查询形成表格然后比较表格。或将其转换为nvarchar并进行字符串比较 【参考方案1】:从 XML 中获取数据非常容易。然后,您可以“一如既往”地比较您的数据。您可以使用“FOR XML”将结果写入新的 XML。
试试这样:
DECLARE @myXML XML=
'<rows>
<row GUEST_ID="13" GUEST_NAME="VEDAT35" GUEST_SURNAME="PALA" ADRESS="IZMIR" CITY="DR" CITY_CODE="35" />
<row GUEST_ID="14" GUEST_NAME="TestGuestName" GUEST_SURNAME="TestSurname" ADRESS="TestAddr" CITY="TestCity" CITY_CODE="11" />
</rows>';
--This is how you retrieve the data
SELECT x.y.value('@GUEST_ID','int')
,x.y.value('@GUEST_NAME','varchar(max)')
,x.y.value('@GUEST_SURNAME','varchar(max)')
,x.y.value('@ADRESS','varchar(max)')
,x.y.value('@CITY','varchar(max)')
,x.y.value('@CITY_CODE','int')
FROM @myXML.nodes('/rows/row') AS x(y)
--This is how you create a new XML with your data
SELECT 13 AS [@GUEST_ID]
,'NewName' AS [@GUEST_NAME]
,'NewSurname' AS [@GUEST_SURNAME]
,'NewAddr' AS [@GUEST_ADRESS]
,'NewCity' AS [@CITY]
,12 AS [@CITY_CODE]
FOR XML PATH('row'),ROOT('rows')
【讨论】:
字段数是变量。我想比较字段值和字段数。 您将找不到可以处理任何可变 XML 的解决方案... SQL Server 可以很好地处理 XML-Data,但您必须假设某种结构... 请提供更多示例数据和预期的输出...... 我在 DB 中有更多的表。我需要 xml 的程序。因为我有更多的字段。。【参考方案2】:样本表
USE [DENEME]
GO
/****** Object: Table [dbo].[GUESTS] Script Date: 17.07.2015 22:19:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[GUESTS](
[GUEST_ID] [int] IDENTITY(1,1) NOT NULL,
[GUEST_NAME] [varchar](50) NULL,
[GUEST_SURNAME] [varchar](50) NULL,
[ADRESS] [varchar](100) NULL,
[CITY] [varchar](50) NULL,
[CITY_CODE] [varchar](10) NULL,
[COUNTRY] [varchar](50) NULL,
[STATUS] [varchar](20) NULL,
[COMMENT] [nvarchar](max) NULL,
PRIMARY KEY CLUSTERED
(
[GUEST_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
USE [DENEME]
GO
/****** Object: Trigger [dbo].[iudt_AutoAuditChanges] Script Date: 17.07.2015 22:20:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[iudt_AutoAuditChanges]
ON [dbo].[GUESTS]
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
SET NOCOUNT ON;
declare @AuditType char(1) /* BEN EKELEDM*/
Declare @v_AuditID bigint
/******************************/
if exists (select * from inserted)
if exists (select * from deleted)
SET @AuditType = 'U'
else
SET @AuditType = 'I'
else
SET @AuditType = 'D'
/******************************/
IF OBJECT_ID('dbo.AutoAudit','U') IS NULL BEGIN
CREATE TABLE [dbo].[AutoAudit]
( [AuditID] bigint identity,
[AuditType] Char(1),
[AuditDate] DateTime,
[AuditUserName] varchar(128),
[TableName] varchar(128) NULL,
[OldContent] XML NULL,
[NewContent] XML NULL,
[Updatedcontent] XML NULL
)
ALTER TABLE dbo.AutoAudit ADD CONSTRAINT
PK_AutoAudit PRIMARY KEY CLUSTERED
(
[AuditID]
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [idx_AutoAudit_TableName_AuditDate] ON [dbo]. [AutoAudit]
( [TableName] ASC,
[AuditDate] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
END
Select * Into #AuditDeleted from deleted
Select * Into #AuditInserted from inserted
While (Select COUNT(*) from #AuditDeleted) > 0 OR (Select COUNT(*) from #AuditInserted) > 0
Begin
INSERT INTO [dbo].[AutoAudit]
( [AuditDate],[AuditType], [AuditUserName], [TableName], [OldContent], [NewContent])
SELECT
GETDATE(),
@AuditType,
SUSER_NAME(),
[TableName]=object_name([parent_obj]),
[OldContent]=CAST((SELECT TOP 1 * FROM #AuditDeleted D FOR XML RAW) AS xml),
[NewContent]=CAST((SELECT TOP 1 * FROM #AuditInserted I FOR XML RAW) AS xml)
FROM sysobjects
WHERE
[xtype] = 'tr'
and [name] = OBJECT_NAME(@@PROCID)
Set @v_AuditID = SCOPE_IDENTITY()
Delete from AutoAudit
Where AuditID = @v_AuditID
AND Convert(varchar(max),oldContent) = Convert(varchar(max),NewContent)
Delete top(1) from #AuditDeleted
Delete top(1) from #AuditInserted
End
END
我正在编写日志程序。 旧内容:
<row GUEST_ID="19" GUEST_NAME="VEDAT" GUEST_SURNAME="PALA" ADRESS="TURKEY" CITY="TOKAT" CITY_CODE="60" />
新内容:
<row GUEST_ID="19" GUEST_NAME="VEDAT60" GUEST_SURNAME="PALA" ADRESS="TURKEY" CITY="TOKAT" CITY_CODE="60" STATUS="other" COMMENT="uptaded fields" />
预期结果: 更新内容:
<row GUEST_NAME="VEDAT60" STATUS="other" COMMENT="uptaded fields" />
我想要比较程序.. 看这张图 IMG]http://i59.tinypic.com/24nfibl.png[/IMG]
【讨论】:
以上是关于SQL Server 中的 XML 列比较的主要内容,如果未能解决你的问题,请参考以下文章
如何比较两个表的列并将值插入到基于 SQL Server 中存储过程中的比较的新表中