none
Datensätze untereinander in ein max-Feld einfügen RRS feed

  • Frage

  • Leider bekomme ich das Update eines nvarchar(max)-Feldes nicht hin:

    CREATE TABLE         [w_langbezeichnung_temp]

    (

    [artikel_GUID]        uniqueidentifier    null,

    [Kurztext]               nvarchar(200)       null,

    [langbezeichnung]               nvarchar(200)      null

    );

    GO

    INSERT INTO         [w_langbezeichnung_temp]

    VALUES            ('A5A1B3B0-BF08-422F-A3A9-000158829741',    'PBS',        'PBS      A123'),

                            ('A5A1B3B0-BF08-422F-A3A9-000158829741',    'SCH',        ' SCH      B4444444'),

                            ('A5A1B3B0-BF08-422F-A3A9-000158829741',    'IMC',        'IMC      999888'),

                            ('7DAF967F-44F3-477A-B8FE-0001A1864FD8',    'SUP',        'SUP      S7777'),

                            ('A838FE00-9FE3-4866-8EFC-00025035E42A',    'SC',          'SC        333222'),

                            ('A838FE00-9FE3-4866-8EFC-00025035E42A',    'ADV',        'ADV      555')

    ;

    GO

    CREATE TABLE         [w_langtext]                              

    (

    [artikel_GUID]                     uniqueidentifier    null,

    [langbezeichnung]                 nvarchar(max)

    );

    GO

    INSERT INTO wilke.dbo.w_langtext        (artikel_GUID)

                                            SELECT       a.artikel_GUID

                                            FROM         wilke.dbo.w_langbezeichnung_temp as a

                                            GROUP BY     artikel_GUID;

    GO

    Ergebnis soll in Tabelle w_langtext so aussehen:

    =================================================== [artikel_GUID]                                                         [langbezeichnung]    

    A5A1B3B0-BF08-422F-A3A9-000158829741            PBS     A123

                                                                                    SCH     B4444444

                                                                                    IMC     999888

    7DAF967F-44F3-477A-B8FE-0001A1864FD8            SUP    S7777

    A838FE00-9FE3-4866-8EFC-00025035E42A           SC       333222

                                                                                   ADV      555

    Nur leider bekomme ich das einfach nicht hin. Vielen Dank schon mal vorab für Eure Hilfe.

    Freitag, 7. August 2020 14:09

Antworten

  • Hi,

    eine Alternative, basierend auf deinem Ansatz wäre folgendes:

    SELECT DISTINCT artikel_GUID,
           REPLACE( CombinedValuesList, '|', CHAR( 13 ) + CHAR( 10 ) )
    FROM   w_langbezeichnung_temp AS outer_table
           CROSS APPLY (
                         SELECT langbezeichnung + '|'
                         FROM   w_langbezeichnung_temp AS inner_table
                         WHERE  inner_table.artikel_GUID = outer_table.artikel_GUID
                         ORDER BY outer_table.Kurztext
                         FOR XML PATH( '' )
                       )
    AS x( CombinedValuesList )

    Diese Abfrage kannst Du dann als Basis für deine INSERT, UPDATE, ... Statements in die Zieltabelle verwenden.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport


    Mittwoch, 12. August 2020 09:59
    Moderator
  • Hi,

    die Daten werden nicht nebeneinander geschrieben, das sieht nur im SSMS so aus, da das SSMS keine Zeilenumbrüche als solche darstellen kann.

    Kopier die Daten mal in Notepad, ... dann siehst Du, dass das schon passt.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport


    Mittwoch, 12. August 2020 11:10
    Moderator

Alle Antworten

  • Question
    Sie können nicht über Ihren eigenen Beitrag abstimmen.
    1

    Hi,

    ab SQL Server 2017 kannst Du dafür STRING_AGG verwenden.

    SELECT   artikel_GUID,
             STRING_AGG( langbezeichnung, CHAR( 13 ) + CHAR( 10 ) ) AS langbezeichnungen
    FROM     w_langbezeichnung_temp
    GROUP BY artikel_GUID

    Für frühere SQL Server Versionen schau dir bitte diesen SO Thread an:

      How to concatenate text from multiple rows into a single text string in SQL server?

    Dort sind wohl so ziemlich alle Varianten zur Zusammenfassung von Zeilenwerten in Textfelder aufgeführt, die es gibt.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Freitag, 7. August 2020 15:06
    Moderator
  • Leider fundktoniert folgendes nicht:

    WITH        Kommaseparierte_Liste as
    (            SELECT        artikel_GUID,    LEFT(MyCommaSeparatedList, LEN(MyCommaSeparatedList)-1) as MyCommaSeparatedList
                FROM        wilke.dbo.w_langbezeichnung c
        CROSS APPLY
                (SELECT        CAST(langbezeichnung as NVARCHAR(max)) + CHAR(131)
                 FROM        wilke.dbo.w_langbezeichnung_temp o
                 WHERE        o.artikel_GUID = c.artikel_GUID
                 ORDER BY    o.Kurztext
        FOR XML PATH('')) AS x(MyCommaSeparatedList)
    )
    UPDATE b
                SET            langbezeichnung = REPLACE(k.MyCommaSeparatedList, CHAR(131), CHAR(13)+CHAR(10))
                FROM        wilke.dbo.w_langbezeichnung b
                INNER JOIN    Kommaseparierte_Liste k
                ON            b.artikel_GUID = k.artikel_GUID
    ;
    GO

    Dienstag, 11. August 2020 14:09
  • Hi,

    das kann schon sein, dass das nciht klappt. Warum hast Du es nicht mal mit meinem Beispiel probiert?


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Dienstag, 11. August 2020 16:55
    Moderator
  • Sorry Stefan,

    ich hatte vergessen darauf hinzuweisen, dass ich den SQL-Server 2012 im Einsatz habe.

    Hast Du eine Lösung?

    Mittwoch, 12. August 2020 05:29
  • Funktioniert denn der erste Teil (also die CTE) separat?

    Was funktioniert dann insgesamt nicht? 

    Brauchst Du bei der CTE NVARCHAR(max) oder reichen auch weniger Zeichen?


    Einen schönen Tag noch, Christoph - http://www.insidesql.org/blogs/cmu

    Mittwoch, 12. August 2020 07:16
    Beantworter
  • Hallo Stefan,

    leider ist das Feld der Datenbank mit nvarchar(max) festgelegt und ich darf dieses nicht ändern. Ist eine Lösung nicht möglich?

    Mittwoch, 12. August 2020 09:34
  • Funktioniert denn der erste Teil (also die CTE) separat?

    Was funktioniert dann insgesamt nicht? 


    Einen schönen Tag noch, Christoph - http://www.insidesql.org/blogs/cmu

    Mittwoch, 12. August 2020 09:43
    Beantworter
  • Hi,

    wie in dem verlinkten Artikel zu lesen, gibt es x verschiedene Möglichkeiten, das Gewünschte zu erreichen.

    Erstell dir doch bspw. einfache eine Skalarfunktion und ruf die dann im SELECT Statement mit auf.

    CREATE FUNCTION [dbo].[fct_ConcatLongNames]( @ArticleGuid uniqueidentifier, @Separator nvarchar( 2 ) ) RETURNS nvarchar( MAX )
    AS
    BEGIN
    
        DECLARE @Output nvarchar( MAX )
        SET @Output = ''
    
        SELECT   @Output = CASE @Output 
                               WHEN '' THEN
                                   CONVERT( nvarchar( 255 ), langbezeichnung )
                               ELSE
                                   @Output + @Separator + CONVERT( nvarchar( MAX ), langbezeichnung )
                               END
        FROM     w_langbezeichnung_temp
        WHERE    artikel_GUID = @ArticleGuid
        ORDER BY langbezeichnung
    
        RETURN   @Output
    END

    Aufruf dann bspw. so:

    SELECT   DISTINCT artikel_GUID,
             dbo.fct_ConcatLongNames( artikel_GUID, CHAR( 13 ) + CHAR( 10 ) ) AS langbezeichnungen
    FROM     w_langbezeichnung_temp
    


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Mittwoch, 12. August 2020 09:51
    Moderator
  • Hi,

    eine Alternative, basierend auf deinem Ansatz wäre folgendes:

    SELECT DISTINCT artikel_GUID,
           REPLACE( CombinedValuesList, '|', CHAR( 13 ) + CHAR( 10 ) )
    FROM   w_langbezeichnung_temp AS outer_table
           CROSS APPLY (
                         SELECT langbezeichnung + '|'
                         FROM   w_langbezeichnung_temp AS inner_table
                         WHERE  inner_table.artikel_GUID = outer_table.artikel_GUID
                         ORDER BY outer_table.Kurztext
                         FOR XML PATH( '' )
                       )
    AS x( CombinedValuesList )

    Diese Abfrage kannst Du dann als Basis für deine INSERT, UPDATE, ... Statements in die Zieltabelle verwenden.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport


    Mittwoch, 12. August 2020 09:59
    Moderator
  • Hallo Stefan,

    leider werden die Daten mit dem Lönsungsansatz nebeneinander geschrieben. Also ohne Zeilenschaltung.

    Was ich nicht verstehe ist, dass durch die REPLACE-Anweisung doch das Zeichen '|' durch die Zeilschaltung CHAR(13) # CHAR(10) ersetzt wird.

    Mittwoch, 12. August 2020 11:08
  • Hi,

    die Daten werden nicht nebeneinander geschrieben, das sieht nur im SSMS so aus, da das SSMS keine Zeilenumbrüche als solche darstellen kann.

    Kopier die Daten mal in Notepad, ... dann siehst Du, dass das schon passt.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport


    Mittwoch, 12. August 2020 11:10
    Moderator
  • Super,

    vielen Dank Stefan.

    Mittwoch, 12. August 2020 11:41