You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将SQL多行多列结果存入nvarchar(max)存储过程输出参数?

解决多列多行数据拼接为字符串的存储过程问题

错误原因分析

你遇到的错误是因为sp_executesql要求@statement和@params参数必须是nvarchar/nchar/ntext类型(推荐用nvarchar(max)),如果你的动态SQL语句变量用了varchar类型,或者参数声明不符合要求,就会触发这个报错。另外,处理多列多行拼接其实不需要依赖动态SQL,用更简洁的方法就能实现。

正确实现方案

1. 先确认表类型定义

注意:user是SQL Server关键字,建议改名比如udt_User避免语法冲突,示例定义如下:

CREATE TYPE dbo.udt_User AS TABLE
(
    Id INT,
    No_user VARCHAR(50),
    Name NVARCHAR(100)
);
GO

2. 存储过程实现(SQL Server 2017+ 推荐用STRING_AGG)

用STRING_AGG直接拼接每行的多列数据,无需动态SQL,代码简洁高效:

CREATE PROCEDURE dbo.some_procedure
    @OutputResult NVARCHAR(MAX) OUTPUT
AS
BEGIN
    SET NOCOUNT ON;

    -- 声明表类型变量并插入测试数据
    DECLARE @userList dbo.udt_User;
    INSERT INTO @userList (Id, No_user, Name)
    VALUES (1, 'U001', '张三'), (2, 'U002', '李四'), (3, 'U003', '王五');

    -- 拼接多列多行数据:每行格式为 "Id:X, 账号:Y, 姓名:Z",用换行分隔
    SELECT @OutputResult = STRING_AGG(
        CONCAT('Id:', Id, ', 账号:', No_user, ', 姓名:', Name),
        CHAR(13) + CHAR(10) -- 可替换为';'等其他分隔符
    )
    FROM @userList;
END
GO

3. 老版本SQL Server(2016及以前)用STUFF+FOR XML PATH

针对低版本数据库,用传统拼接方式实现:

CREATE PROCEDURE dbo.some_procedure
    @OutputResult NVARCHAR(MAX) OUTPUT
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @userList dbo.udt_User;
    INSERT INTO @userList (Id, No_user, Name)
    VALUES (1, 'U001', '张三'), (2, 'U002', '李四'), (3, 'U003', '王五');

    -- 拼接多列数据,用STUFF去掉开头的分隔符
    SELECT @OutputResult = STUFF(
        (
            SELECT CHAR(13) + CHAR(10) + CONCAT('Id:', Id, ', 账号:', No_user, ', 姓名:', Name)
            FROM @userList
            FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)'),
        1, 2, '' -- 去掉开头的换行符(CHAR(13)+CHAR(10)占2个字符)
    );
END
GO

4. 如果必须用动态SQL(不推荐)

若因特殊场景必须使用动态SQL,需确保@statement和参数声明均为nvarchar类型:

CREATE PROCEDURE dbo.some_procedure
    @OutputResult NVARCHAR(MAX) OUTPUT
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @userList dbo.udt_User;
    INSERT INTO @userList (Id, No_user, Name)
    VALUES (1, 'U001', '张三'), (2, 'U002', '李四'), (3, 'U003', '王五');

    DECLARE @sql NVARCHAR(MAX); -- 必须为NVARCHAR类型
    SET @sql = N'
        SELECT @Result = STRING_AGG(
            CONCAT(''Id:'', Id, '', 账号:'', No_user, '', 姓名:'', Name),
            CHAR(13)+CHAR(10)
        )
        FROM @userList';

    -- 执行动态SQL,参数声明必须是NVARCHAR类型
    EXEC sp_executesql @sql,
        N'@userList dbo.udt_User READONLY, @Result NVARCHAR(MAX) OUTPUT',
        @userList = @userList,
        @Result = @OutputResult OUTPUT;
END
GO

关键注意事项

  • 避免使用SQL Server关键字(如user)作为表类型、变量名称,防止语法冲突。
  • 动态SQL中,字符串内的单引号需要用两个单引号转义('')。
  • sp_executesql的@statement和@params参数必须是nvarchar类型,不能用varchar。

内容的提问来源于stack exchange,提问作者1029Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 15:10:44