操作数类型冲突:varchar与用户定义的表类型不兼容

时间:2013-08-07 14:06:36

标签: sql sql-server sql-server-2008 user-defined-functions user-defined-types

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

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

不兼容

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

2 个答案:

答案 0 :(得分: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 demo

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

答案 1 :(得分:0)

使用STUFF..FOR XML PATH构造与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 (不确定我的列是否合适,但您会明白这一点)

相关问题