标签: xml

使用xml参数插入多个数据时如何避免使用Merge查询?

我正在尝试使用一组值更新表。数组中的每一项都包含与 SQL Server 数据库表中的行匹配的信息。如果该行已存在于表中,我们将使用给定数组中的信息更新该行。否则,我们在表中插入一个新行。我已经基本上描述了 upsert。

现在,我试图在采用 XML 参数的存储过程中实现这一点。我使用 XML 而不是表值参数的原因是,执行后者时,我必须在 SQL 中创建自定义类型并将此类型与存储过程相关联。如果我以后更改了存储过程或数据库架构中的某些内容,则必须重做存储过程和自定义类型。我想避免这种情况。此外,TVP 相对于 XML 的优势对我的情况没有用,因为我的数据数组大小永远不会超过 1000。这意味着我不能使用这里提出的解决方案:How to insert multiple records using XML in SQL server 2008

此外,这里的类似讨论(UPSERT - 是否有更好的替代 MERGE 或 @@rowcount?)与我所问的不同,因为我试图将行插入到表中。

我希望我可以简单地使用以下一组查询来更新 xml 中的值。但这行不通。当输入是单行时,这种方法应该有效。

begin tran
   update table with (serializable) set select * from xml_param
   where key = @key

   if @@rowcount = 0
   begin
      insert table (key, ...) values (@key,..)
   end
commit tran
Run Code Online (Sandbox Code Playgroud)

下一个替代方法是使用详尽的 IF EXISTS 或其以下形式的变体之一。但是,我以次优效率为由拒绝了这一点:

IF (SELECT COUNT ... ) > 0 …
Run Code Online (Sandbox Code Playgroud)

xml sql-server stored-procedures t-sql upsert

11
推荐指数
1
解决办法
1万
查看次数

返回属性不包含特定字符的 xml 序列

考虑以下简单的 XML:

<xml>
  <customer name="Max">
    <email address="me@you.com" />
  </customer>
  <customer name="Erik">
    <email address="erik@your-mom.com" />
  </customer>
  <customer name="Brent">
    <email address="brentcom" />
  </customer>
</xml>
Run Code Online (Sandbox Code Playgroud)

我想要得到的名单<Customer>,其中序列address中的属性<email>项并没有包含@

所以,我希望输出看起来像:

<customer name="Brent">
  <email address="brentcom" />
</customer>
Run Code Online (Sandbox Code Playgroud)

麦克维

DECLARE @x XML = '<xml>
<customer name="Max"><email address="me@you.com" /></customer>
<customer name="Erik"><email address="erik@your-mom.com" /></customer>
<customer name="Brent"><email address="brentcom" /></customer>
</xml>';
Run Code Online (Sandbox Code Playgroud)

这个查询:

SELECT WithValidEmail = @x.query('/xml/customer/email[contains(@address, "@")]')
    , WithInvalidEmail = @x.query('/xml/customer/email[contains(@address, "@")] = False');
Run Code Online (Sandbox Code Playgroud)

返回:

????????????????????????????????????????????????????????????
?            WithValidEmail             ? WithInvalidEmail ? …
Run Code Online (Sandbox Code Playgroud)

xml sql-server xquery

10
推荐指数
1
解决办法
2706
查看次数

元素名称的变量

我有这个 tSQL 代码可以正常工作:

SELECT 
c.logguid,
a.b.value('./PropertyValue', 'varchar(max)') asd
  FROM [dnn].[dbo].[EventLog2] c

cross apply sss.nodes('/LogProperties/LogProperty[PropertyName=sql:variable("@x") and PropertyValue=sql:variable("@y")]') as a(b)
Run Code Online (Sandbox Code Playgroud)

但是,我希望能够做的是传入许多对值的动态列表,这些值对在每个值之间进行 OR 运算,即

SELECT 
c.logguid,
a.b.value('./PropertyValue', 'varchar(max)') asd
  FROM [dnn].[dbo].[EventLog2] c

cross apply sss.nodes(
'/LogProperties/LogProperty[PropertyName=sql:variable("@x") and PropertyValue=sql:variable("@y")
or
PropertyName=sql:variable("@a") and PropertyValue=sql:variable("@b")
]'
) as a(b)
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?

xml t-sql

9
推荐指数
1
解决办法
389
查看次数

估计与实际行差异(实际远小于估计) - 排序

我正在运行一个查询,该查询正在处理 XML 文档中的一些节点。我估计的子树成本以数百万计,似乎这一切都来自 SQL Server 对我通过 XPath 从 xml 列中提取的某些数据执行的排序操作。Sort 操作的估计行数约为 1900 万,而实际行数约为 800。查询本身运行得相当好(1 - 2 秒),但这种差异让我想知道查询性能以及为什么会这样差别这么大?

performance xml sql-server query-performance

9
推荐指数
1
解决办法
2108
查看次数

在 XML 列中编辑单个条目的最简单方法?

据我了解,MS SQL Server Management Studio 不允许通过 GUI 直接编辑/替换 XML 列中的条目(复制/粘贴不起作用等)。

替换 XML 列中单个条目的最简单选项是什么?对于 XML 列值,我是否必须使用与 UPDATE/REPLACE 不同的东西?

xml sql-server sql-server-2012

9
推荐指数
1
解决办法
7万
查看次数

SQL 行与 XML PATH 和 STUFF 的连接给出聚合 sql 错误

我正在尝试查询两个表并获得如下结果:

Section    Names
shoes      AccountName1, AccountName2, AccountName3
books      AccountName1
Run Code Online (Sandbox Code Playgroud)

这些表是:

CREATE TABLE dbo.TableA(ID INT, Section varchar(64), AccountId varchar(64));

INSERT dbo.TableA(ID, Section, AccountId) VALUES
(1 ,'shoes','A1'),
(2 ,'shoes','A2'),
(3 ,'shoes','A3'),
(4 ,'books','A1');

CREATE TABLE dbo.TableB(AccountId varchar(20), Name varchar(64));

INSERT dbo.TableB(AccountId, Name) VALUES
('A1','AccountName1'),
('A2','AccountName2'),
('A3','AccountNAme3');
Run Code Online (Sandbox Code Playgroud)

我看到一些回答说使用“XML PATH”和“STUFF”来查询数据以获得我正在寻找的结果,但我认为缺少一些东西。我尝试了以下查询并收到错误消息:

列“a.AccountId”在选择列表中无效,因为它既不包含在聚合函数中也不包含在 GROUP BY 子句中。

我在任一查询的 SELECT 子句中都没有它,但我认为错误是因为 AccountId 在 TableA 中不是唯一的。

这是我目前正在尝试正常工作的查询。

SELECT section, names= STUFF((
    SELECT ', ' + Name FROM TableB as b 
WHERE AccountId = b.AccountId
FOR XML PATH('')), 1, 1, …
Run Code Online (Sandbox Code Playgroud)

xml sql-server sql-server-2008-r2 concat

9
推荐指数
2
解决办法
7万
查看次数

如何仅使用 Xpath 从 SQL Server 中的空 XML 标记返回空值?

我有一个应用程序,用于存储有关 XML 列中记录的各种用户定义的数据点。我无法控制这些是如何存储或更新的。

当我查询一列时,它可以返回 3 个值中的 1 个:

  1. 价值
  2. 空值
  3. 空字符串

$64 问题我想使用 xpath 将这些空字符串作为空值返回。

我找到了很多关于将 null 作为空字符串返回的答案,但没有这样的方法。

当有人删除该值时,他们会以这种方式结束,而不是删除标签,而是将其空白到一个<value />标签。当从未设置值时会出现空值。他们没有包括 xsi:nil。

我已经用 case 语句完成了它:

    select
    so.SalesOrderId,
    Case
        when sopc.value('(Value)[1]','smalldatetime') IS null then Null
        when sopc.value('(Value)[1]','smalldatetime') ='' then Null
        Else sopc.value('(Value)[1]','smalldatetime')
    End as sopc
    From
    SalesOrders so
    Outer apply so.CustomColumns.nodes('/CustomColumnsCollection/CustomColumn[Name="ProjCompleted"]') sopc(sopc)
Run Code Online (Sandbox Code Playgroud)

但这感觉效率低下,而且这不是唯一的列,因此它使代码变得冗长且难以维护。

编辑以包含示例数据

SalesOrderId    CustomColumns
SO 1            "<CustomColumnsCollection>
                   <CustomColumn>
                     <Name>ProjCompleted</Name>
                     <DataType>1</DataType>
                     <Value />
                   </CustomColumn>
                 </CustomColumnsCollection>"
SO 2           "<CustomColumnsCollection>
                  <CustomColumn>
                     <Name>ProjCompleted</Name>
                     <DataType>1</DataType>
                     <Value>'2017-11-21'</Value>
                  </CustomColumn>
                </CustomColumnsCollection>"
SO 3           "<CustomColumnsCollection>
                </CustomColumnsCollection>" …
Run Code Online (Sandbox Code Playgroud)

xml sql-server-2008-r2

9
推荐指数
1
解决办法
9196
查看次数

Xml 索引,行数慢

在以下情况下,我没有得到索引查找。而不是<Number>xxx</Number>像这篇文章那样插入到 xml 列中为什么当 where 子句过滤 `value()` 时不使用二级选择性索引?, 用这个 xml 插入 100k 行<SomeText>NiceText</SomeText>和类似数量的 this <SomeText>MoreText</SomeText>。不需要是100k。只需要很多。然后添加索引

create selective xml index SIX_T on dbo.T(XMLDoc) for
(
    pathXQUERY = '/SomeText' as xquery 'xs:string' maxlength(8) singleton
);
Run Code Online (Sandbox Code Playgroud)

和二级索引

create xml index SIX_T_pathXQUERY on dbo.T(XMLDoc)
  using xml index SIX_T for (pathXQUERY);
Run Code Online (Sandbox Code Playgroud)

然后数数

select count(*)
from dbo.T as T
where T.XMLDoc.exist('/SomeText[. eq "MoreText"]') = 1;
Run Code Online (Sandbox Code Playgroud)

请注意,它不使用索引查找并且“慢”。数百万行可能需要几秒钟。如果我在标准列中插入相同的值并向其添加索引并执行

select count(id)
    from dbo.T as T where SomeTextColumn = 'MoreText'
Run Code Online (Sandbox Code Playgroud)

我立即得到结果。在 sql server 18.3.1 …

performance index xml sql-server execution-plan query-performance

9
推荐指数
2
解决办法
530
查看次数

为什么 SQL 使用相同的 XML 查询结构进行索引扫描和查找?

我已经设置了一个测试来对 SQL 服务器中的 xml 性能进行基准测试。

测试设置

  • 一百万行数据
  • XML 定义的具有主键的列
  • 一个主要的 XML 索引
  • 路径上的辅助 XML 索引
  • XML 数据在格式上相似,但在每个文档中都有可变的标签名称

表和索引设计

CREATE TABLE [dbo].[xml_Test]
(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [GUID] [varchar](50) NULL,
    [JSON_Data] [varchar](max) NULL,
    [XML_Data] [xml] NULL,
    CONSTRAINT [PK_xml_Test] PRIMARY KEY CLUSTERED ([ID] ASC)
);

ALTER TABLE [dbo].[xml_Test] ADD  CONSTRAINT [DF_xml_Test_GUID]  DEFAULT (newid()) FOR [GUID];
ALTER TABLE [dbo].[xml_Test] ADD  CONSTRAINT [PK_xml_Test] PRIMARY KEY CLUSTERED ([ID] ASC);

CREATE PRIMARY XML INDEX [PK_xml] ON [dbo].[xml_Test]
(   [XML_Data]);

CREATE XML INDEX [IX_xml_Path] ON [dbo].[xml_Test] …
Run Code Online (Sandbox Code Playgroud)

performance xml sql-server t-sql index-tuning

9
推荐指数
2
解决办法
226
查看次数

确定文件夹中多个 .DTSX 包文件的 PackageFormatVersion

Kenneth Fisher 发表了一篇关于如何确定我的 SSIS 包是什么 SQL 版本的博客文章2015 年 4 月。

它有一个表,其中列出了哪些 SQL 版本映射到PackageFormatVersion在 XML 元数据中找到的 SSIS 包。这在查看 1 个单独的包时很有用。

我有一个包含大约 100 个 SSIS.DTSX包的文件夹,我需要知道它们都是哪个 SQL 版本。

如何批量确定文件夹(文件系统)中PackageFormatVersion多个.DTSX包的(即 SQL 版本)是什么?

最终目标是确定哪个是正确的 TFS 版本来获取和实施以将这些包放入,因为当前不存在源代码控制系统。Kenneth 提供的表将帮助我回答这个问题,但首先我需要确认包 SQL 版本是什么。

假设我没有安装 BIDS 或 SSDT。

假设所需的输出是这样的,其中管道指定了一个新列:

PackageFilename | PackageFormatVersion
--------------------------------------
Package1.dtsx   | 3
Package2.dtsx   | 4
Run Code Online (Sandbox Code Playgroud)

欢迎使用 PowerShell、TSQL、可以抓取目录结构的 3rd 方工具或其他工具。

xml sql-server ssis powershell t-sql

8
推荐指数
1
解决办法
1274
查看次数