【问题标题】:Int Placeholder %d in xp_sprintf - SQL Serverxp_sprintf 中的 Int 占位符 %d - SQL Server
【发布时间】:2017-08-22 17:33:21
【问题描述】:

我有一个 XML 模板,我需要使用 xp_sprintf 根据表中的行值构造一个 XML。此外,该表具有 Int 和 Bit 值。

表格架构:StudentMark

CREATE TABLE [dbo].[StudentMark]
(
    [StudentMarkId] [int] IDENTITY(1,1) NOT NULL,
    [StudentId] [uniqueidentifier] NOT NULL,
    [SubjectId] [uniqueidentifier] NOT NULL,
    [Score] [int] NOT NULL,
    [ScoreInfo] [xml] NOT NULL,
    [GeneratedOn] [datetime2](2) NOT NULL,
    [IsPass] [bit] NOT NULL,
    CONSTRAINT [PK_StudentMark] 
       PRIMARY KEY CLUSTERED ([StudentMarkId] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

样本种子数据

INSERT INTO [dbo].[StudentMark] ([StudentId], [SubjectId], [ScoreInfo], GeneratedOn], [Score], [IsPass])
VALUES ('FC3CB475-B480-4129-9190-6DE880E2D581', '0D72F79E-FB48-4D3E-9906-B78A9D105081', '<StudentMarkAttribute xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></StudentMarkAttribute>', '2017-08-10 10:10:15', 95, 1),
       ('0F4EF48C-93E3-41AA-8295-F6B0E8D8C3A2', '0D72F79E-FB48-4D3E-9906-B78A9D105081', '<StudentMarkAttribute xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></StudentMarkAttribute>', '2017-08-10 10:10:15', 100, 1),
       ('0F4EF48C-93E3-41AA-8295-F6B0E8D8C3A2', 'AB172272-D2E9-49E1-8040-6117BB6743DB', '<StudentMarkAttribute xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></StudentMarkAttribute>', '2017-08-16 09:06:20', 25, 0),
       ('FC3CB475-B480-4129-9190-6DE880E2D581', 'AB172272-D2E9-49E1-8040-6117BB6743DB', '<StudentMarkAttribute xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></StudentMarkAttribute>', '2017-08-16 09:06:20', 82, 1);

要求:我需要将行转换为以下 XML,并且需要在相应记录的列 [dbo].[StudentMark].[ScoreInfo] 中进行更新。

XML 模板

<ScoreInfo>
    <StudentMarkId>%d</StudentMarkId>
    <StudentId>%s</StudentId>
    <SubjectId>%s</SubjectId>
    <Score>%d</Score>
    <GeneratedOn>%s</GeneratedOn>
    <IsPass>%d</IsPass>
</ScoreInfo>

我从 Stackoverflow 问题之一尝试了以下示例代码

declare @name varchar(150)
set @name = 'John'

declare @score int
set @score = 75

DECLARE @ret varchar(500)
exec master..xp_sprintf @ret OUTPUT, 'Hello %s, your score is %d', @name, @score

PRINT @ret

我收到以下错误消息

执行扩展存储过程时出错:无效的参数类型消息 50003,级别 1,状态 0

请帮助我如何使用指定的表[dbo].[StudentMark]构造模板XML

我提出了以下问题

请帮助我如何使用数字格式说明符等,

【问题讨论】:

  • 为什么要使用 xp_sprintf?
  • 你有什么替代功能吗?如果是,请帮助我...
  • 你可以从阅读FOR XML (SQL Server)开始
  • @JamesZ - 好的,感谢您的帮助,但在此 xp_sprintf 中,我们如何使用 %d ?你能澄清一下吗...
  • 你不能使用 %d,xp_sprintf 只支持 %s。您必须手动将@score 转换为字符串类型,然后将其与格式字符串“Hello %s, your score is %s”一起传递给 xp_sprintf。

标签: sql sql-server printf string-formatting format-specifiers


【解决方案1】:

xp_sprintf only supports string arguments and %s placeholders,因此无法在 SQL Server 中使用 %d 占位符。您必须将数字转换为字符串,然后使用它来填充 %s 占位符。

满足您要求的最简单方法是使用内置的 XML 功能。

update [target]
    SET [ScoreInfo] = [XmlValue]
    FROM [dbo].[StudentMark] AS target 
    JOIN (
             SELECT [StudentMarkId],
                (
                   SELECT 
                      [StudentMarkId],[StudentId], [SubjectId], [GeneratedOn], [Score], [IsPass] 
                    FROM [dbo].[StudentMark] AS innr 
                    WHERE outr.[StudentMarkId] = innr.[StudentMarkId]
                    FOR XML PATH('ScoreInfo'), TYPE
                 ) as [XmlValue]
             FROM [dbo].[StudentMark] AS outr
         ) AS source 
     ON target.[StudentMarkId] = source.[StudentMarkId]

将设置 ScoreInfo 等于:

 <ScoreInfo>
    <StudentMarkId>%d</StudentMarkId>
    <StudentId>%s</StudentId>
    <SubjectId>%s</SubjectId>
    <Score>%d</Score>
    <GeneratedOn>%s</GeneratedOn>
    <IsPass>%d</IsPass>
 </ScoreInfo>

对于每一行,在单个查询中。

【讨论】:

  • Yours 是我要求的部分答案,但我的问题是如何在xp_sprintf 中使用%d
【解决方案2】:

因为 xp_sprintf 只支持 "%s" 你需要 CAST 任何数值到 VARCHAR

修改您的示例如下:

声明 @ret         VARCHAR(500)
声明 @name    VARCHAR(150)
声明 @val         VARCHAR(10)
声明 @score INT

设置@name = '约翰'
设置@score = 75
设置@val = CAST(@score as VARCHAR(10))

EXEC master..xp_sprintf @ret OUTPUT, 'Hello %s, your score is %s', @name, @val

打印@ret

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-14
    • 1970-01-01
    • 2013-11-27
    • 2019-03-25
    • 2022-01-01
    • 1970-01-01
    • 2019-07-25
    相关资源
    最近更新 更多