2

我创建了一个用户定义的表类型:

CREATE TYPE dbo.ListTableType AS TABLE(
    ITEM varchar(500) NULL
)

我在一个函数中利用它:

CREATE FUNCTION dbo.fn_list_to_string
(
    @LIST dbo.ListTableType READONLY
)
RETURNS varchar(max)
AS
BEGIN
    DECLARE @RESULT varchar(max)
    SET @RESULT = ''

    DECLARE @NL AS CHAR(2) = CHAR(13) + CHAR(10)

    SELECT @RESULT = @RESULT + ITEM + @NL FROM @LIST
    SET @RESULT = SUBSTRING(@RESULT, 1, LEN(@RESULT) - 1)

    RETURN @RESULT
END

最后,我尝试在一个简单的选择中使用这个函数:

SELECT
    P.PROGRAM_ID,
    PROGRAM_NAME,
    PROGRAM_DESC,
    P.STATUS_ID,
    STATUS_DESC,
    P.CONTACT_SID,
    I.FIRST_NAME + ' ' + I.LAST_NAME as CONTACT_NAME,
    P.CLARITY_ID,
    dbo.fn_list_to_string(
        (   SELECT CONVERT(varchar,CLARITY_ID) as ITEM
            FROM dbo.MUSEUM_PROGRAM_PROJECTS as A
            JOIN dbo.MUSEUM_PROJECTS as B on B.PROJECT_ID = A.PROJECT_ID
            WHERE PROGRAM_ID = P.PROGRAM_ID )
    ) as PROJECT_CLARITY_IDS
FROM dbo.MUSEUM_PROGRAMS as P
LEFT JOIN dbo.MUSEUM_PROGRAM_STATUS_TYPES as S on S.STATUS_ID = P.STATUS_ID
LEFT JOIN dbo.v_IDVAULT_ENRICHED_CURRENT_EMPLOYEES as I on I.[SID] = P.CONTACT_SID

但我得到这个错误:

操作数类型冲突:varchar 与 ListTableType 不兼容

知道为什么吗?此外,如果有另一种[更优雅]的方式来实现我想要做的事情,我也愿意接受建议!提前致谢!

4

2 回答 2

2

这是一个简单的FOR XML PATH技术演示,它通过一个非常简单的子查询来完成所有这些工作,没有表类型或效率极低的多语句表值函数等。

USE tempdb;
GO

CREATE TABLE dbo.P(Program_ID INT);

CREATE TABLE dbo.M(Clarity_ID INT, Program_ID INT);

INSERT dbo.P VALUES(1),(2),(3),(4);

INSERT dbo.M VALUES(1,1),(1,2),(2,3),(3,2),(1,4),(4,1);

SELECT
    P.PROGRAM_ID,
    PROJECT_CLARITY_IDS = STUFF((
      SELECT CHAR(13)+CHAR(10)+CONVERT(VARCHAR(12),Clarity_ID)
        FROM dbo.M WHERE Program_ID = p.Program_ID
        FOR XML PATH(''), TYPE).value('.[1]','nvarchar(max)'),1,2,'')
 FROM dbo.P AS p;

SQLfiddle 演示

输出在 SQLfiddle 中或在 Management Studio 中的网格结果中看起来不正确,因为它们出于显示目的去除了回车/换行符,但您可以CHAR(13)+CHAR(10)用两个逗号或分号或其他东西替换以验证是否有两个那里的字符。

于 2013-08-07T14:26:39.203 回答
0

STUFF..FOR XML PATHconcatenation 的construct 与CTE 结合使用将获得您想要的结果。像这样的东西:

WITH CTE_PROJECT_CLARITIES AS
(
    SELECT DISTINCT PROGRAM_ID
            , STUFF((
                SELECT CHAR(13) + CHAR(10) + CONVERT(varchar(11),CLARITY_ID) 
                FROM dbo.MUSEUM_PROGRAM_PROJECTS as A
                    JOIN dbo.MUSEUM_PROJECTS as B on B.PROJECT_ID = A.PROJECT_ID
                WHERE A.PROGRAM_ID = X.PROGRAM_ID
                FOR XML PATH ('')),1,2,'') AS PROJECT_CLARITY_IDS
    FROM MUSEUM_PROGRAM_PROJECTS X
)
SELECT
    P.PROGRAM_ID,
    PROGRAM_NAME,
    PROGRAM_DESC,
    P.STATUS_ID,
    STATUS_DESC,
    P.CONTACT_SID,
    I.FIRST_NAME + ' ' + I.LAST_NAME as CONTACT_NAME,
    P.CLARITY_ID,
    X.PROJECT_CLARITY_IDS
FROM dbo.MUSEUM_PROGRAMS as P
LEFT JOIN dbo.MUSEUM_PROGRAM_STATUS_TYPES as S on S.STATUS_ID = P.STATUS_ID
LEFT JOIN dbo.v_IDVAULT_ENRICHED_CURRENT_EMPLOYEES as I on I.[SID] = P.CONTACT_SID
LEFT JOIN CTE_PROJECT_CLARITIES X ON X.PROGRAM_ID = p.PROGRAM_ID

SQLFiddle DEMO(不确定我的列是否正确,但你会明白的)

于 2013-08-07T14:33:27.090 回答