문제

I created a User-Defined Table Type:

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

I leverage it in a function:

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

Finally, I try to use this function in a simple select:

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

But I get this error:

Operand type clash: varchar is incompatible with ListTableType

Any idea why? Also if there's another [more elegant] way to achieve what I'm trying to do I'm open to suggestions as well! Thanks in advance!

도움이 되었습니까?

해결책

Here is a simple demonstration of the FOR XML PATH technique which does all of this with a very simple subquery and no table types or extremely inefficient multi-statement table-valued functions etc.

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

The output doesn't look right in SQLfiddle or in results to grid in Management Studio, because they strip out carriage returns/line feeds for display purposes, but you can replace CHAR(13)+CHAR(10) with two commas or semi-colons or something to verify that there are two characters there.

다른 팁

Using STUFF..FOR XML PATH construct for concatanation in combination with CTE will get the results you'd like. Something like this:

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 (not sure if I got the columns right, but you'll get the idea)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top