Avatar billede binderup Nybegynder
17. januar 2006 - 10:43 Der er 1 kommentar og
1 løsning

Rekursiv ændring af Kollation i MySQL (4.1)

Er der en nem måde hvor man kan ændre de enkelte kollonners kollation via en enkelt kommando (uden at man skal ind for at ændre det manuelt pr kolonne)?

Jeg har nemlig 84 tabeller der alle er oprettet med latin_swedish og jeg vil gerne have det til at være danish
Avatar billede arne_v Ekspert
17. januar 2006 - 12:18 #1
du kan nemt finde alle tabeller i en database og alle kolonner i en tabel

så det er ikke svlrt at kode i PHP/Java/C++/C#/ASP/whatever
Avatar billede binderup Nybegynder
17. januar 2006 - 15:25 #2
Jeg fik det løst ved noget hurtig kode.

koden herunde er en klasse som render en database igennem og ændre alle kolonner af en bestemt type til at have danish som collation. jeg har klippet nogle metoder ud fra en gammel db klasse og tilføjet lidt ekstra.

-- code begin --
<?php

// definitions
    $dbHost = 'localhost';
    $dbBase = 'xxxxxxx';
    $dbUser = 'xxxxxxx';
    $dbPass = 'xxxxxxx';
   
// includes
    require_once("DB.php");    //PEAR DB
   
// classes
    class fixCollation extends DB {
        var $dbHandler;
        var $dbHost;
        var $dbBase;
        var $dbUser;
        var $dbPass;
        var $dbType = 'mysql';
       
        var $charset;
        var $collation;

        /**
        * construct
        *
        * @param string $server
        * @param string $user
        * @param string $pass
        * @param string $database
        * @param string $charset
        * @param string $collation
        * @return fixCollation
        */
        function fixCollation($server, $user, $pass, $database, $charset, $collation){
            $this->dbHost = $server;
            $this->dbBase = $database;
            $this->dbPass = $pass;
            $this->dbUser = $user;
           
            $this->charset = $charset;
            $this->collation = $collation;
           
            $this->set_dbHandler();
        }
       
        /**
        * forbindelses holder til DB
        *
        */
        function set_dbHandler(){
            $this->dbHandler = $this->connect();
        }
       
        /**
        * Connect til DB
        *
        * @return dbLink
        */
        function connect(){
            //setting up connection to DB
            $dblink = DB::connect("$this->dbType://$this->dbUser:$this->dbPass@$this->dbHost/$this->dbBase");
            return $dblink;
        }
   
        /**
        * Lukker forbindelse til database
        *
        */
        function disconnect(){
            $this->dbHandler->disconnect();
        }
       
        /**
        * metode til at hente query resultater som objekt array
        *
        * @param string $sql
        * @return array
        */
        function sql_ReturnResultObject($sql){
            //setting the fetch mode
            $this->dbHandler->setFetchMode(DB_FETCHMODE_OBJECT);
   
            //getting the data
            $returnData = $this->dbHandler->getAll($sql);
   
            return $returnData;
        }
       
        /**
        * metode til at hente query resultater som asso array
        *
        * @param string $sql
        * @return array
        */
        function sql_ReturnResultAssoc($sql){
            //setting the fetch mode
            $this->dbHandler->setFetchMode(DB_FETCHMODE_ASSOC);
   
            //getting the data
            $returnData = $this->dbHandler->getAll($sql);
   
            return $returnData;
        }
       
        /**
        * metode til at køre en direkte query
        *
        * @param string $SQL
        */
        function run_query($SQL){
            $this->dbHandler->query($SQL);
        }
       
        /**
        * metode til at hente et array ud med navnene på de tabeller der er i databasen
        *
        * @return array
        */
        function return_tables(){
            $result = $this->sql_ReturnResultAssoc("SHOW TABLES FROM ". $this->dbBase);
           
            foreach ($result as $key => $value) {
                $returnData[] = $value['Tables_in_'.$this->dbBase];
            }
           
            return $returnData;
        }               

        /**
        * metode til at hente en tabels kolonner ud som array
        *
        * @param varchar $table
        * @return array
        */
        function return_columns($table){
            $result = $this->sql_ReturnResultAssoc("SHOW COLUMNS FROM ". $table);
            return $result;
        }
       
        /**
        * Denne metode løber igennem en tabels kolonner og ændre dem der opfylder type betingelserne
        *
        * @param varchar $table
        */
        function set_column_fields_collation($table){
            $field_names = $this->return_columns($table);
           
            //array der indeholder de typer fields der er behov for med ændring
            $field_types = array('char','varchar','tinytext','text','mediumtext','longtext','enum','set');
           
            for ($i=0; $i<sizeof($field_names); $i++){
                //værdien for Type skal renses så den ikke indeholder længde - jeg er kun intereseret i type betegnelsen og ikke hvor meget den fylder
                if (strstr($field_names[$i]['Type'], "(")) {
                    $tmp = preg_match("/(.*)\((.*)/", $field_names[$i]['Type'], $matches);
                    $tmp = $matches[1];
                } else {
                    $tmp = $field_names[$i]['Type'];
                }
               
                //hvis tmp overholder standarden - så lav SQL sætning
                if (in_array($tmp, $field_types)) {
                    $SQL_update[] = "ALTER TABLE `".$table."` CHANGE `".$field_names[$i]['Field']."` `".$field_names[$i]['Field']."` ".$matches[0]." CHARACTER SET ".$this->charset." COLLATE ".$this->collation."";
                }
            }
           
            //Der loopes igennem de rows der kan ændres
            for ($i=0; $i<sizeof($SQL_update); $i++){
                $this->run_query($SQL_update[$i]);
            }
        }
       
        /**
        * Denne metode render den definerede database igennem og sørger for at tabeller og felter bliver sat til
        *
        */
        function update_entire_database(){
            //først henter vi de tabeller der skal bruges
            $tables = $this->return_tables();
           
            //vi looger igennem tabellerne
            for ($i=0; $i<sizeof($tables); $i++){
                echo 'Opdaterer ' . $tables[$i] . '<br>';
               
                //først opdaterer vi default værdien for tabellen
                $this->run_query("ALTER TABLE `".$tables[$i]."` DEFAULT CHARACTER SET ".$this->charset." COLLATE ".$this->collation."");
               
                //herefter alle felterne
                $this->set_column_fields_collation($tables[$i]);
               
                echo '&nbsp;&nbsp;&nbsp; (done)<br><br>';
            }
           
           
        }
       
    }
   
// Opretter objekt samt kørsel af metode til opdatering
    $updateObj = new fixCollation($dbHost, $dbUser, $dbPass, $dbBase, "latin1", "latin1_danish_ci");
    $updateObj->update_entire_database();

?>
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester