Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Boήθεια με Insert into

Îåêßíçóå áðü ôï ìÝëïò neoklis. Τελευταία δημοσίευση από το μέλος spaceman στις 15-12-2010, 16:24. Υπάρχουν 27 απαντήσεις.
Σελίδα 1 από 2 (28 εγγραφές)   1 2 >
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  13-12-2010, 14:06 61559

    Boήθεια με Insert into

    Παιδιά καλησπέρα,

    Σε έναν πίνακα που έχει γίνει imported από txt file έχει διπλοεγγραφές (id,Descr). Η βάση είναι σε SQL 2008.

    π.χ.

     ID          Description

    1032381 Το καινούριο μου αυτοκίνητο

    1032381 είναι ένα ηλεκτρικό αυτοκίνητο

     Αυτό που θέλω, ειναι να κάνω insert into σε κενό πίνακα, με κλειδί το ID και να έχω όλο το description σε μια γραμμή. Πιθανόν εκτος από διπλοεγγραφές να έχω και περισσότερες.. Πρώτη φορά αντιμετωπίζω κάτι τέτοιο και η αλήθεια είναι ότι αν και φαινομενικά έιναι εύκολο, έχω κολλήσει..

     ID          Description

    1032381 Το καινούριο μου αυτοκίνητο είναι ένα ηλεκτρικό αυτοκίνητο


    Dionisis
  •  13-12-2010, 14:32 61560 σε απάντηση της 61559

    Απ: Boήθεια με Insert into

    Μια πρόχειρη λύση περιλαμβάνει τη δημιουργία μιας UDF που "ενώνει" όλα τα strings από records με το ίδιο id σε ένα:
    (myTable είναι το όνομα του table, και id, description τα ονόματα των πεδίων). Υποθέτω οτι το id είναι int.
    CREATE FUNCTION fn_concatit (@id int) returns nvarchar(max)
    as
    BEGIN
    	declare @val nvarchar(max)
    	
    	select @val = coalesce (@val,'') + description + ' '
    	from myTable
    	where id=@id
    
    	return left(@val, len(@val)-1)
    END

    Και μετά το τρέχεις κάπως έτσι:

    select 
    	id
    	, dbo.fn_concatit(id) as mydescription 
    from 	myTable
    group by id
    Στη function προσθέτω και ένα space ανάμεσα στα strings και απλώς στην επιστροφή "τρώω" το τελευταίο space.

    Αυτό θα σου δώσει ένα result set που μπορείς να το κάνεις insert σε ένα καινούριο πίνακα.



    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  13-12-2010, 14:32 61561 σε απάντηση της 61559

    Απ: Boήθεια με Insert into

    DECLARE @t TABLE (id SMALLINT, Descr_txt NVARCHAR(200) COLLATE database_default, order_fld TINYINT)
    
    INSERT INTO @t(id, Descr_txt, order_fld)
    VALUES (1, 'This is', 1), (1, 'a test for', 2), (1, 'id 1', 3),
    (2, 'This is', 1), (2, 'for', 2), (2, 'id 2', 3),
    (3, 'And', 1), (3, 'another for', 2), (3, 'id 3', 3)
    
    
    SELECT distinct_ids.id, (SELECT t.Descr_txt AS 'data()' FROM @t AS t WHERE t.id = distinct_ids.id ORDER BY t.order_fld FOR XML PATH('')) AS concat_columns
    FROM (SELECT DISTINCT id FROM @t) AS distinct_ids
     
    --HTH--
  •  13-12-2010, 14:33 61562 σε απάντηση της 61559

    Απ: Boήθεια με Insert into

    Μια πολύ γρήγορη λύση για το πρόβλημα σου όπως το λες είναι η παρακατώ μιας και θα το χρησιμοποιήσεις απαξ

    create table Original ( ID int ,Description nvarchar(max) )
    go
    create table NewOriginal ( ID int ,Description nvarchar(max) )
    go

    INSERT INTO Original values ( 1, 'Antonis' )
    INSERT INTO Original values ( 1, 'Chatzipavlis' )
    INSERT INTO Original values ( 2, 'dot' )
    INSERT INTO Original values ( 2, 'Net' )
    INSERT INTO Original values ( 2, 'Zone' )
    INSERT INTO Original values ( 2, '.gr' )
    go

    select * from Original
    go

    DECLARE tcursor CURSOR
    READ_ONLY
    FOR select id,description from original

    DECLARE @lid int , @id int , @desc nvarchar(max), @newdesc nvarchar(max)
    OPEN tcursor

    FETCH NEXT FROM tcursor INTO @id, @desc
    set @lid = @id
    set @newdesc=''
    WHILE (@@fetch_status <> -1)
    BEGIN
     IF (@@fetch_status <> -2)
     BEGIN
      if @lid <> @id
      begin
       insert into NewOriginal values ( @lid , @newdesc)
       set @lid = @id
       set @newdesc=@desc
      end
      else
      begin
       set @newdesc = @newdesc + @desc
      end
     END
     FETCH NEXT FROM tcursor INTO @id, @desc
    END
    insert into NewOriginal values ( @lid , @newdesc)

    CLOSE tcursor
    DEALLOCATE tcursor
    GO

    select * from NewOriginal
    go


    Antonios Chatzipavlis

  •  13-12-2010, 14:39 61563 σε απάντηση της 61562

    Απ: Boήθεια με Insert into

    Τον πνίξαμε στις λύσεις τον άνθρωπο :)
    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  13-12-2010, 14:43 61564 σε απάντηση της 61563

    Απ: Boήθεια με Insert into

    Δεν με πνίξατε..... με ξελιγώσατε...Smile

    Καλύτερα όμως έτσι, καθώς θα έχω την δυνατότητα να δω περισσότερες από μία λύσεις..

    Ευχαριστώ


    Dionisis
  •  13-12-2010, 14:50 61565 σε απάντηση της 61560

    Απ: Boήθεια με Insert into

    cap:
    Στη function προσθέτω και ένα space ανάμεσα στα strings και απλώς στην επιστροφή "τρώω" το τελευταίο space.
     
    SELECT LEN('test'), LEN('test '), LEFT('test ', LEN('test ')-1)
    --HTH--
  •  13-12-2010, 15:04 61566 σε απάντηση της 61565

    Απ: Boήθεια με Insert into

    Yes, right. Αλλαξε την γραμμή return στην udf σε:

    return rtrim(@val)


    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  13-12-2010, 15:07 61567 σε απάντηση της 61566

    Απ: Boήθεια με Insert into

    Η εναλλακτικά (πείτε μου όμως αν δεν είναι ενδεδειγμένη η χρήση της datalength εδώ):
    Ο λόγος που αβίαστα χρησιμοποίησα τη len είναι από κεκτημένη ταχύτητα, απλά χρησιμοποιούσα το ίδιο function για να φτιάχνω delimited strings οπου εκεί το len έδινε το σωστό μήκος. Τώρα με το space, την πατήσαμε :)

    return left(@val, datalength(@val)-1)

    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  13-12-2010, 15:11 61568 σε απάντηση της 61566

    Απ: Boήθεια με Insert into

    cap:
    return rtrim(@val)

    VALUES(1032381, N'Το καινούριο μου αυτοκίνητο'), (1032381, N'είναι ένα ηλεκτρικό αυτοκίνητο                     ')

    select 
    	id
    	, dbo.fn_concatit(id) as mydescription 
    from 	myTable
    group by id
    1032381, 'Το καινούριο μου αυτοκίνητο είναι ένα ηλεκτρικό αυτοκίνητο'
    --HTH--
  •  13-12-2010, 15:17 61569 σε απάντηση της 61568

    Απ: Boήθεια με Insert into

    Spaceman, γι'αυτό έγραψα αμέσως από κάτω την datalength. Αν και θα έπρεπε να σε ευχαριστήσω που υποδεικνύεις αυτά τα flaws (και θα το κάνω - ευχαριστώ), αισθάνομαι λιγάκι σαν το παιδάκι που το διορθώνει ο δάσκαλος - χώρια που όσοι διαβάζουν ίσως δεν αντιλαμβάνονται αμέσως γιατί γράφεις αυτό που γράφεις. Θα ήταν ίσως λίγο πιό χρήσιμο για τους υπόλοιπους φίλους ένα σχόλιο του στυλ "ξέρεις, η rtrim θα σου σβήσει όλα τα trailing spaces οπότε αν έχεις πολλά και τα θέλεις θα έχεις πρόβλημα", ή "η len δεν λαμβάνει υπόψη της τα trailing spaces οπότε το value που θα πάρεις θα αποχωριστεί τον τελευταίο του πραγματικό χαρακτήρα". 


    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  13-12-2010, 15:23 61570 σε απάντηση της 61569

    Απ: Boήθεια με Insert into

    CREATE FUNCTION dbo.fn_concatit (@id int) returns nvarchar(max)
    as
    BEGIN
    	declare @val nvarchar(max)
    	
    	select @val =  ISNULL(@val, N'') + N' ' +description
    	from dbo.myTable
    	where id=@id
    	--there should be an order by here
    	
    	return STUFF(@val, 1, 1, N'')
    END

    --HTH--

  •  13-12-2010, 15:25 61571 σε απάντηση της 61569

    Απ: Boήθεια με Insert into

    H λύση που προτείνει ο spaceman είναι νομίζω η αρτιότερη απλά πρέπει να ξέρεις άριστη t-sql για να την καταλάβεις η δικιά μου είναι η πεπατημενη λύση που παίζει παντού με το αντίστοιχο performance penalty. Θα σου πρότεινα να χρησιμοποιήσεις την λύση του spaceman ακόμα και αν δεν την πολυκαταλαβαίνεις στην περίπτωση που αυτό που θέλεις να κάνεις τώρα θα το επαναλαμβάνεις συχνά. Αν πάλι όχι τότε έχεις 3 τρόπους για να κάνεις το ίδιο πράγμα τονίζοντας πάλι ότι του spaceman είναι η βέλτιστη.
    Antonios Chatzipavlis

  •  13-12-2010, 15:42 61572 σε απάντηση της 61571

    Απ: Boήθεια με Insert into

    Για εκπαιδευτικούς λόγους, ας δούμε τι είχα κάνει λάθος εγώ και τι διορθώθηκε από την έκδοση του spaceman:

    Δική μου udf:
    CREATE FUNCTION fn_concatit (@id int) returns nvarchar(max)
    as
    BEGIN
    	declare @val nvarchar(max)
    	
    	select @val = coalesce (@val,'') + description + ' '
    	from myTable
    	where id=@id
    
    	return left(@val, len(@val)-1)
    END
    Διορθωμένη από spaceman:
    CREATE FUNCTION dbo.fn_concatit (@id int) returns nvarchar(max)
    as
    BEGIN
    	declare @val nvarchar(max)
    	
    	select @val =  ISNULL(@val, N'') + N' ' +description
    	from dbo.myTable
    	where id=@id
    	--there should be an order by here
    	
    	return STUFF(@val, 1, 1, N'')
    END

    Το πρώτο λάθος στη δική μου έκδοση ήταν οτι δεν είχε γίνει create στο dbo schema, κάτι το οποίο μπορεί μεν να είναι implied σε ορισμένες περιπτώσεις, αλλά το σωστότερο είναι να δηλώνεται.
    Το δεύτερο λάθος ήταν ότι δεν χρησιμοποίησα unicode strings στο concatenation (Ν), ενώ στην ουσία επιστρέφω nvarchar.
    Η χρήση της isnull έναντι της coalesce στο συγκεκριμένο σενάριο δεν ξέρω πού υπερτερεί, ας βοηθήσουν οι υπόλοιποι.
    Το order by φαντάζομαι οτι είναι για performance reasons; Αν οχι, θα ήθελα να γνωρίζω και εγώ γιατί πρέπει να έχουμε order by.
    Τελος, το return value από εμένα δεν ήταν σωστό ούτε με τη χρήση της rtrim (μπορεί να έχουμε trailing spaces που να τα χρειαζόμαστε) ούτε με τη χρήση της len (δεν μετράει spaces). Οπότε, αυτό που έκανε ο spaceman είναι να προσθέτει το κάθε space ΠΡΙΝ και όχι μετά, έτσι ωστε το τελικό του string να έχει ένα leading space, το οποίο κόβει με τη βοήθεια της stuff. Αυτό ήταν και το πιό σημαντικό σφάλμα.




    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  13-12-2010, 15:52 61573 σε απάντηση της 61572

    Απ: Boήθεια με Insert into

    Επειδή έιναι κάτι που θα επαναλαμβάνετε θα χρησιμοποίησω function.  Μέχρι να δω τα νέα ποστ είχα ήδη παίξει με την λύση που μου πρότεινε ο cap. Σε κάποιες περιπτώσεις το description ήταν null και χτύπαγε error στο return. Και ενώ πειραματιζόμουν για να το διορθώσω, είδα τα νεότερα post. Δοκίμασα  α)return rtrim(@val) β)return left(@val, datalength(@val)-1) και στις 2 περιπτώσεις παίζει μια χαρά.

    Θα δοκιμάσω και του spaceman...


    Dionisis
Σελίδα 1 από 2 (28 εγγραφές)   1 2 >
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems