Цикл таблицы (без использования курсора) для объединения данных - PullRequest
1 голос
/ 15 декабря 2010

Пожалуйста, посмотрите / запустите следующий скрипт.

DECLARE @Products Table (   PId int )

INSERT @Products SELECT 100
INSERT @Products SELECT 101
INSERT @Products SELECT 102

DECLARE @Stff Table ( Stid int, StaffName VARCHAR(20) )

INSERT @Stff SELECT 301, 'White'
INSERT @Stff SELECT 302, 'Green'

DECLARE @Items Table
(
    ItemId int,
    PIdFK int,
    StIdFK int,
    CreatedDate DateTime,
    Notes varchar(100),
    NotesHistory varchar(2000)
)

INSERT INTO @Items SELECT 1, 100, 301, GETDATE(), Null, NULL
INSERT INTO @Items SELECT 2, 101, 301, GETDATE(), Null, NULL
INSERT INTO @Items SELECT 3, 101, 301, DATEADD(DD, 1, GETDATE()), 'Hello Dear', NULL
INSERT INTO @Items SELECT 4, 101, 301, DATEADD(DD, 2, GETDATE()), 'Did you get my msg?', NULL
INSERT INTO @Items SELECT 5, 102, 302, GETDATE(), Null, NULL
INSERT INTO @Items SELECT 6, 102, 302, DATEADD(DD, 1, GETDATE()), Null, NULL
INSERT INTO @Items SELECT 7, 102, 302, DATEADD(DD, 3, GETDATE()), 'How are you doing?', NULL
INSERT INTO @Items SELECT 8, 102, 302, DATEADD(DD, 4, GETDATE()), 'Your Items are ready.', NULL

SELECT * FROM @Items

DECLARE @ItemsHistory Table
(
    ItemHisotryId int,
    ItemIdFK int,
    StIdFK int,
    NotesHisotry varchar(200),
    CreatedDate DATETIME
)

INSERT INTO @ItemsHistory SELECT 1, 1, 301, NULL, GETDATE()
INSERT INTO @ItemsHistory SELECT 2, 2, 301, NULL, GETDATE()
INSERT INTO @ItemsHistory SELECT 3, 3, 301, 'Hello Dear', DATEADD(DD, 1, GETDATE())
INSERT INTO @ItemsHistory SELECT 4, 4, 301, 'Dimd you get my msg?', DATEADD(DD, 2, GETDATE())
INSERT INTO @ItemsHistory SELECT 5, 5, 302, NULL, GETDATE()
INSERT INTO @ItemsHistory SELECT 6, 6, 302, NULL, DATEADD(DD, 1, GETDATE())
INSERT INTO @ItemsHistory SELECT 7, 7, 302, 'How are you doing?', DATEADD(DD, 3, GETDATE())
INSERT INTO @ItemsHistory SELECT 8, 8, 302, 'Your Items are ready', DATEADD(DD, 4, GETDATE())

Я хочу объединить все данные в столбце Notes таблицы Items и столбце NotsHistory таблицы ItemsHistory в одну строку. Фактически я хочу обновить столбец Items.NotesHistory таблицы Items с помощьювсе ItemsHistory.NotesHisotry столбец, относящийся к PID

Можете ли вы помочь это без использования курсора.Я использую SQL Server 2008, поэтому CTE может это сделать, но я не понимаю, как мне этого добиться.

Результирующая строка должна выглядеть следующим образом:

<b>Items.CreaedDate - Items.StaffName: <b/> Items.Notes <br/><b>ItemsHisotryCreatedDate - ItemsHistory.StaffName <b> ItemsHistory.NotesHistory

Следующая часть будет добавленаиз таблицы ItemsHistory для каждой записи добавлено уникальное 'PId'

<br/><b>ItemsHisotryCreatedDate - ItemsHistory.StaffName <b> ItemsHistory.NotesHistory

Спасибо.

Ответы [ 2 ]

4 голосов
/ 15 декабря 2010

Вы можете объединить без цикла через что-то вроде ниже; просто добавьте свой собственный запрос / объединения и т. д. по мере необходимости:

DECLARE @s varchar(max) = ''

SELECT @s = @s + '<br/><b>' + CONVERT(varchar(10), i.CreatedDate, 101) + '</b>' + ISNULL(i.Notes, '')
FROM @Items i

SELECT @s

(вы должны убедиться, что там нет NULL с)

но не делай этого!

База данных , а не место для создания HTML; Не в последнюю очередь, это открывает вам огромные уязвимости XSRF. Я сделал бы это на уровне пользовательского интерфейса, используя соответствующие функции кодирования html, предоставляемые той платформой, которую вы используете. Слепая конкатенация строк в виде html практически не уступает слепой конкатенации пользовательских строк в TSQL (вместо использования параметров); в лучшем случае форматирование будет затруднено (неправильная обработка < и т. д.) - в худшем случае вы подвергаете своих пользователей прямому риску атаки.

1 голос
/ 15 декабря 2010

Как насчет чего-то вроде

;WITH Vals AS (
        SELECT  PIdFK,
                Notes,
                ItemIdFK
        FROM    @ItemsHistory ih INNER JOIN
                @Items i    ON  ih.ItemIdFK = i.ItemId
        WHERE   Notes IS NOT NULL
)
SELECT 
        v.PIdFK,
        STUFF( 
               (SELECT 
                    ', ' + v2.Notes 
                    FROM Vals v2 
                    WHERE v.PIdFK=v2.PIdFK 
                    ORDER BY v2.ItemIdFK 
                    FOR XML PATH(''), TYPE 
               ).value('.','varchar(max)') 
               ,1,2, '' 
          ) AS Notes 
FROM Vals v 
GROUP BY v.PIdFK
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...