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

 

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

c# byte[] vs sql byte

Îåêßíçóå áðü ôï ìÝëïò evagelos. Τελευταία δημοσίευση από το μέλος evagelos στις 10-10-2014, 18:51. Υπάρχουν 9 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  09-10-2014, 13:14 75756

    c# byte[] vs sql byte

    Γεια σας, παιδια,

    εχω ένα πεδίο σε μια βαση με τυπο [CCCMultiTXT1] [image] NULL

     

    εχω ένα textbox και τα μετατρέπω σε byte[] για να τα αποθηκευσω και στη συνεχεια τα διαβαζω.

    οι δυο functions:


            static byte[] GetBytes(string str)
            {
                byte[] bytes = new byte[str.Length * sizeof(char)];
                System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
                return bytes;
            }

     και

             private string ConvByteToStr(byte[] myByte)
            {
                if (myByte != null)
                {
                    char[] chars = new char[myByte.Length / sizeof(char)];
                    System.Buffer.BlockCopy(myByte, 0, chars, 0, myByte.Length);
                    return new string(chars);
                }
                else
                {
                    return "";
                }
            }

     

     

    όλα παιζουν καλα.

    Παω τώρα να αποθηκευσω την τιμή από ένα sql query αλλα όταν τα διαβαζω μου βγαινουν "κινεζικα"

    UPDATE myTbl SET MultiTXT1= (CONVERT(IMAGE,'ВЪЗГЛАВНИЦА МЕКА MICROFIBER-1000 50Χ70')) WHERE CODE='003365'
    UPDATE myTbl SET CCCMultiTXT1= CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), 'ВЪЗГЛАВНИЦА МЕКА MICROFIBER-1000 50Χ70')) WHERE

    εχω δοκιμάσει και τα 2

     

    αυτά που βλέπω στο textbox είναι:

     ВЪЗГЛАВНИЦА МЕКА MICROFIBER-1000 50Χ70

    όταν τα περναω από την c#

    㼿㼿㼿㼿㼿‿㼿㼿䴠䍉佒䥆䕂ⵒ〱〰㔠휰〷

    όταν τρέχω από το sql.

    Η βάση έχει collation Greek_CI_AS αν παιζει ρολο

     

    τι δεν κανω σωστά και που;

     

    Ευχαριστώ εκ των προτερων

  •  09-10-2014, 14:32 75757 σε απάντηση της 75756

    Απ: c# byte[] vs sql byte

    Καλημέρα,

    Επειδή η "τακτική" που χρησιμοποιείς είναι λίγο "ανορθόδοξη" τι ακριβώς προσπαθείς να κάνεις;

     

    George J.
     


    George J. Capnias: Χειροπρακτικός Υπολογιστών, Ύψιστος Γκουράρχης της Κουμπουτερολογίας
    w: capnias.org, t: @gcapnias, l: gr.linkedin.com/in/gcapnias
    dotNETZone.gr News
  •  09-10-2014, 14:36 75758 σε απάντηση της 75756

    Απ: c# byte[] vs sql byte

    Τί προσπαθείς να κάνεις? Γιατί κάνεις όλο αυτό το γύρω-γύρω αντί να σώσεις απλά το string ως nvarchar? Άντε nvarchar(max) αν πραγματικά περιμένεις blobs μεγαλύτερα από 4Κ.

    Ο SQL Server και το .NET δεν έχουν κανένα πρόβλημα να δουλέψουν με Unicode - τα .NET strings είναι Unicode έτσι κι αλλιώς, ενώ ο SQL Server υποστηρίζει Unicode data μεσω των nchar, nvarchar τύπων - says the guy who sells tickets to Korea and Russia.

    Για να μην έχεις πρόβλημα, απλά όρισε τα πεδία σου ως nvarchar και φρόντισε να αποθηκεύσεις σωστά τα strings:

    • Όταν γράφεις T-SQL πρέπει να βάζεις το 'N' μπροστά από το string για να καταλάβει η βάση ότι στέλνεις Unicode και όχι ASCII, π.χ.

         UPDATE myTbl SET MultiTXT1=Ν'ВЪЗГЛАВНИЦА МЕКА MICROFIBER-1000 50Χ70' WHERE CODE='003365'

    • Όταν γράφεις στη βάση, φρόντισε να χρησιμοποιείς parameterized queries των οποίων ο τύπος είναι nvarchar αντί για χύμα SQL. Μπορείς να χρησιμοποιήσεις και χύμα SQL φτάνει να βάλεις το N. 

    Όσο για το τί συμβαίνει με τα conversions - σκέψου πόσα και ποιά conversions κάνεις. Κάποια τα κάνεις στην C# θεωρώντας UTF16, μετά τα στέλνεις στη βάση όπου τα 2bytes τα χειρίζεσαι λες και είναι 1-byte ASCII (varchar), μετά τα μετατρέπεις από και προς το codepage της βάσης (Greek), και τέλος άλλο ένα conversion από της βάσης στο codepage του χρήστη, όταν διαβάζεις από τη βάση και προσπαθείς να μετατρέψεις ASCII σε Unicode θεωρώντας ότι το codepage είναι αυτό του χρήστη ...

    Δεν αξίζει καν να προσπαθήσεις να καταλάβεις σε ποιό σημείο καταστράφηκαν τα δεδομένα καθώς η 2η μετατροπή πρέπει ήδη να έχει καταστρέψει χαρακτήρες που δεν εμφανίζονται στα ελληνικά.

    Είχα γράψει και ένα σχετικό blog post πριν άπειρα χρόνια, "Ο SQL Server δεν χρειάζεται κόλπα για να υποστηρίξει ελληνικά" το οποίο περιέχει πάνω-κάτω αυτά που έγραψα και παραπάνω 


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  09-10-2014, 15:31 75759 σε απάντηση της 75758

    Απ: c# byte[] vs sql byte

    Δυστυχώς δεν τα πεδία δεν μπορούν να είναι σε nvarchar αλλα ειτε varchar ειτε image  και δεν μπορώ να κανω κατι σε αυτό

    γιαυτό και το κανω ετσι

  •  09-10-2014, 15:56 75760 σε απάντηση της 75759

    Απ: c# byte[] vs sql byte

    Από τεχνικής σκοπίας, αυτό που ΔΕΝ γίνεται, είναι αυτό που προσπαθείς να κάνεις.  Οι unicode τύποι υπήρχαν εξαπανέκαθεν και δεν κοστίζει τίποτε να τους χρησιμοποιήσεις. Αντίθετα, θέλει δουλειά για να κάνεις τη ζημιά και δουλειά για να τη διορθώσεις.

    Το οποίο σημαίνει ότι το πρόβλημα είναι πολιτικό και χρεώνεσαι εσύ το κόστος επειδή κάποιος άλλος δεν θέλει να παραδεχθεί το λάθος.

    Μετά τον καφέ θα αναφέρω τις διάφορες πολιτικές λύσεις και ίσως κάποιες ματσακωνιές που μπορεί να καλύψουν το πρόβλημα - όχι να το λύσουν. Η T-SQL δεν έχει πολιτικές προεκτάσεις.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  09-10-2014, 16:15 75761 σε απάντηση της 75760

    Απ: c# byte[] vs sql byte

    Το ξέρω αυτό, δυστηχώς θα πρεπει να ζησω με αυτό, ως ότου το "διορθώσουν" και κανουν ΚΑΙ την ζωή μου πιο ευκολη

  •  09-10-2014, 16:36 75762 σε απάντηση της 75760

    Απ: c# byte[] vs sql byte

    Καταρχήν, είναι αδύνατο να αποθηκεύσεις μαξιλαράκια σε ελληνικά, κυριλικά, αγγλικά στην ίδια στήλη varchar, καθώς όλα τα codepages έχουν χαρακτήρες που δεν εμφανίζονται στα άλλα. Οπότε ή θα χρειαστείς διαφορετικές στήλες/πίνακες για το καθένα, με διαφορετικό collation ή θα πρέπει να χρησιμοποιήσεις varbinary(max) για να σώσεις το Unicode ως bytes. Και οι δύο είναι γεμάτες μειονεκτήματα.

    Ξεκινώντας από τη δεύτερη λύση, αυτό που προσπαθείς να κάνεις:

    • Δεν κερδίζεις τίποτε σε χώρο, αφού είσαι αναγκασμένος να σώζεις 2 bytes ανά χαρακτήρα 
    • Για να δείξεις τα δεδομένα, πάλι σε NVARCHAR θα τα μετατρέψεις
    • Χάνεις τη δυνατότητα αναζήτησης στο πεδίο πέρα από το απλό '='. Δεν θα μπορείς να ψάξεις για "Μαξιλαράκια%" ή οτιδήποτε παρόμοιο
    • Περιορίζεις δραματικά τη δυνατότητα indexing καθώς συγκρίσεις του στυλ 'από έως', 'μεγαλύτερο','μικρότερο' παύουν να δουλεύουν.
    • Αν προσπαθήσεις να κάνεις σύγκριση με την decoded τιμή χάνεις τα indexes - εκτός και αν μετατρέπεις όλα τα κριτήρια αναζήτησης σε binary πρώτα
    • Οποιεσδήποτε συγκρίσεις *δεν* θα καταλαβαίνουν τις σχέσεις μεταξύ πχ. i και I. Διαφορετικά bytes σημαίνει ανισότητα και τελείωσες. Που σημαίνει "Μαξιλαράκια"<>"ΜΑΞΙΛΑΡΑΚΙΑ"
    • Μειωμένη απόδοση της βάσης γιατί τα blobs αποθηκεύονται εκτός του table row. Που σημαίνει κάθε φορά που θα θέλεις να δείξεις τα μαξιλαράκια η βάση θα πρέπει να κάνει διπλή δουλειά
    • Ακατάλυπτα δεδομένα. Προφανώς
    • Μεγάλη πιθανότητα καταστροφής των δεδομένων, αρκεί ένας να κάνει μία εγγραφή με λάθος τρόπο, πχ να προσπαθήσει να κάνει CONVERT όπως δοκίμασες κι εσύ.

    Για να κάνεις τη μετατροπή από/προς μπορείς να χρησιμοποιήσεις την CONVERT βάζοντας όμως ως τύπο το NVARCHAR, ποτέ VARCHAR για να αποφύγεις το μπάχαλο με τα διαφορετικά codepages. Για παράδειγμα:

    declare @myParam nvarchar(40)=N'ВЪЗГЛАВНИЦА'

     

    SELECT CONVERT(VARBINARY(40),@myParam);

    ----------------------------------------------------------------------------------

    0x12042A04170413041B04100412041D04180426041004

    SELECT CONVERT(NVARCHAR(40),0x12042A04170413041B04100412041D04180426041004);

    ----------------------------------------

    ВЪЗГЛАВНИЦА

    Προσοχή στον τύπο της μεταβλητής. Είναι nvarchar και δεν πρέπει να αλλάξει, διαφορετικά θα έχεις πάλι το πρόβλημα της απώλειας χαρακτήρων κατά τη μετατροπής από ένα codepage σε άλλο.

     

    Μπορείς να προσπαθήσεις να κάνεις το ίδιο και σε κώδικα, αλλά το θέμα παραμένει. Τα δεδομένα πρέπει να μετακινούνται πάντα από Unicode σε binary, ποτέ προσπάθεια μετατροπής σε varchar. Αυτό σημαίνει ότι οποιοδήποτε query, ADO.NET command parameter ή stored procedure θα πρέπει να δουλεύει είτε με varbinary είτε με nvarchar αλλιώς θα έχεις απώλειες.

    Όσο για την πρώτη λύση, μπορείς να προσθέσεις ένα ακόμα πεδίο varchar για κάθε γλώσσα που θέλεις να υποστηρίξεις με COLLATION συμβατό με τη γλώσσα. Αν κατά λάθος αποθηκεύσεις δεδομένα που δεν ταιριάζουν, τα έχασες. Όταν αποθηκεύεις varchar θα πρέπει να φροντίζεις να θέτεις και το COLLATION σε SQL. Αν αποθηκεύεις nvarchar ο SQL Server θα κάνει τη μετατροπή σωστά, φτάνει να μην βρεθούν άκυροι χαρακτήρες (πχ. ελληνικά και ρώσικα στην αγγλική στήλη).

    Φυσικά αυξάνει η πολυπλοκότητα, το μέγεθος των πινάκων, η πιθανότητα λάθους, αλλά τουλάχιστον μπορείς να διαβάσεις τα δεδομένα

    Ουσιαστικές λύσεις τώρα:

    • Αν το "δεν γίνεται" το λέει το αφεντικό, βρες άλλη δουλειά.
    • Αν το λέει ο manager, υπολόγισε το κόστος σε ανθρωποώρες, το δικό σου για την υλοποίηση και το κόστος από λάθη (συν το marketing cost αν τα μαξιλαράκια εμφανιστούν σαν κουτάκια) και πες του ότι θα πρέπει να το αναλάβει αυτός
    • Αν το λέει ο κατασκευαστής της εφαρμογής που χρησιμοποιείς, πες του να τη διορθώσει. Αν αρνείται, χρέωσε του τις ώρες που θα χρειαστείς για να τη διορθώσεις εσύ
    • Αν αρνείται, βρες άλλη. Υπάρχουν και άνθρωποι που ξέρουν από βάσεις
    • Αν ο κατασκευαστής είναι Microsoft partner και προσπαθεί να τα ρίξει στον SQL Server και αρνείται να διορθώσει το πρόβλημα, κάρφωσε τον στην Microsoft Hellas. Θα χαρούν να του μιλήσουν
    • Μπορείς φυσικά να του κάνεις και αγωγή γιατί σου πούλησε εν γνώση του ελλατωματικό προϊόν. Το μισό DNZ θα έρθουν μάρτυρες υπέρ σου.

    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  09-10-2014, 23:36 75765 σε απάντηση της 75762

    Απ: c# byte[] vs sql byte

    ok , το εκανα, τώρα όσον αφορά τις προτάσεις που λες συμφωνω 100%.

    εχει σχεδιαστει λαθος η βαση και τώρα μαλλον καπου το χανουν ή δεν τους νοιάζει.

    Ερώτηση. Αν αποφασισουν κ γυρισουν όλα τα varchar σε nvarchar, υπάρχει προβλημα και κινδυνος με τα δεδομάνα; (εγκυκλοπαιδική ερώτηση)

     

  •  10-10-2014, 07:50 75768 σε απάντηση της 75765

    Απ: c# byte[] vs sql byte

    Έχασα λίγο τη μπάλα σ' αυτό το thread. Αν όμως κατάλαβα καλά, και αν τα πράγματα συνεχίσουν να έχουν ως έχουν, ίσως θα ήταν καλύτερο να χρησιμοποιήσεις μία transliteration library, όπως τη Unidecode. Κάτι έτοιμο για SQL δε βρήκα, οπότε στον server θα πρέπει να γράψεις εσύ τα functions, χρησιμοπιώντας ως οδηγό τον κώδικα της Unidecode. Από ακαδημαϊκή άποψη, το εγχείρημα είναι ενδιαφέρον. Από επαγγελματική, όμως....

    Ακόμα κι ένας άνθρωπος μπορεί ν' αλλάξει τον κόσμο. Μη θέλεις να κυβερνήσεις. Απλά δείξε το μονοπάτι κι ο κόσμος θ' ακολουθήσει!!
  •  10-10-2014, 18:51 75769 σε απάντηση της 75768

    Απ: c# byte[] vs sql byte

    Βασικά η λύση του Παναγιώτη με καλυψε

    Σε ευχαριστώ 

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