XML-funksjoner i MySQL
-
Upload
harald-groven -
Category
Technology
-
view
478 -
download
1
Transcript of XML-funksjoner i MySQL
XML-funksjoner i MySQL
Xpath-støtte i Mysql
Kom i versjon 5.1.5 (nytt™ i 2008!)
Ikke en del av ANSI-SQL
To nye SQL-funksjonerExtractValue()UpdateXML()
fra år 2000
Mysql's xml-funksjoner er modellert etter Oracle sin.
Syntaks
Tar to argumenter SELECT EXTRACTVALUE(<felt>,'xpathuttrykk') AS nyttaliasFROM <tabell>;
Settes et alias (AS), er dette heretter nytt navn på (den deriverte) kolonna. Settes det ikke, er funksjonen navn kolonnenavn :-(
Xpath-uttrykk'/HTML/HEAD/TITLE' Henter CDATA fra <TITLE>
'//TABLE' Henter alle CDATA under <TABLE>
'//TABLE/TD/TR[1]' Henter innholdet fra første rad i en tabell
'/contacts/contactData/adr/street' er det samme som '//street' (hvis en forekomst)
'/admissionInfo/studentPlaces/@places' innholdet av atributtet @places
'//contactData[@userDefined="visit"]/adr/street' gate som har attributt visit i contactData
'//refProgram/@idRef' du kan referere til brukerdefinerte variablerdefiners i SET @vendor_id := 'vilbli.no' ;
Forutsetninger- valid- case sensitive
og så ... virkeligheten :-O
øvelser her:
www.groven.no/harald/Xpath_i_Mysql
Hvordan få data inn ?LOAD DATA INFILE '/filbane/CDM_PRIMARY.xml'INTO TABLE `cdmxml_org` CHARACTER SET latin1 FIELDS TERMINATED BY 'føkkyou' LINES TERMINATED BY '<orgUnit>' ;
Leser ikke tegnsett dynamsk :-( FIELDS defaulter til '\t'LINES defaulter til '\n'Databasen må finnes først CREATE TABLE IF NOT EXISTS cdm.cdmxml_org ( xmldata longtext NOT NULL) DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci;
Datatransformasjon
Hvordan flytte data fra en tabell til en annen i SQL, når tabellene har forskjellig antall kolonner og forskjellig kolonnenavn? Dette uten å dumpe ut som tekst? GUIer for dette: MS-Access, FilemakerAltova MapForce (xml)
Fancy INSERTs Neandertalmetoden: INSERT INTO `tabell` VALUES('greie1', 'verdi1', 'verdi2') ; INSERT INTO `tabell` VALUES('greie2', 'verdi1', 'verdi2') ;
Einstein-metoden: INSERT INTO `tabell` SELECT felt1, felt2, felt3 FROM `annentabell`;
Forutsetninger: - Samme antall kolonner som i destinasjonstabellen !- Samme navn på kolonnnene som i destinasjonstabellen !! - Ingen constraint-violations under importen !!!
INSERT INTO SELECTs
Hva om kolonnene har forskjellig navn i de to tabellene? INSERT INTO tabell SELECT A.etelleranna AS felt1, A.hurra AS felt2, A.foobar AS felt3 FROM annentabell A; Tabellalias lar deg omdøpe kolonnne
INSERT INTO SELECTs
Hva om du skal smæsje i hop data fra mange tabeller? INSERT INTO tabell SELECT A.etelleranna AS felt1, A.hurra AS felt2, AA.foobar AS felt3FROM annentabell ALEFT JOIN endaentabell AA ON (AA.id=A.id) ;
INSERT INTO SELECTsHva om innholdet er av forskjellig datatype eller skal modifiseres? INSERT INTO tabell SELECT CONCAT('http://', A.nettadresse) AS url, REPLACE(A.innhold,' faen!',' huffda!') AS artikkel, (DATEDIFF (U.login, '1970-01-01 00:00:00') *86400) AS unixtid, 'ja' AS svar -- konstant FROM annentabell A; Tips: Behold originaldata i egne tabeller, og fiks opp med funksjoner. Kjør på nytt om eksport går til helvete
Feilhåndtering under INSERT
INSERT INTO SELECTStopper ved integritetsbrudd (integrety violation), som fx to poster med samme nøkkelverdi eller ulovlige verdier. For lange verdier trunkeres uten å stoppe innsetninga.
INSERT IGNORE INTO SELECT Kjører videre ved feilmeldinger så lengen syntaksen i skriptet er gyldig.... Nyttig for å "etterfylle"
REPLACE INTO SELECT genial !!Hvis det finnes en post med samme primærnøkkelID -> UPDATE Hvis det ikke finnes noen post med primærnøkkelID -> INSERT
CREATE TABLE SELECTHva om tabellen det skal settes inn data i ikke finnes fra før? CREATE TABLE flunkendenytabell SELECT felt1, felt2, felt3 FROM `annentabell`; Gjetter datatype på felt1, felt2 og felt3 ut fra innholdet og oppretter tabell med disse feltene.
Sekvensverdier / sequencesGenrere en unik ID for en tabell som ikke har det fra før
CREATE TABLE tabellTMP(nid INT(8) NOT NULL AUTO_INCREMENT, PRIMARY KEY (nid)) SELECT * FROM tabell_1;
Kolonna nid får nå en haug med ferske IDer...Hvis disse idnummerene er "brukt opp" kan en kjøreUPDATE tabellTMP SET nid=(nid+24999) ; NB slå av primærnøkkelen, skru på igjen etter
CREATE TABLE SELECTProblemer med tabeller laga av CREATE TABLE SELECTs: - For romslige datatyper som LONGTEXT, eller BLOB ved NULL-input. -> uindekserbar :-( - Har du ikke data under opprettinga kan den lage INT(0)
-- Løsning :-D CREATE TABLE IF NOT EXISTS cdm.orgunit ( org_importid INT(10) AUTO_INCREMENT NOT NULL, vendor_id VARCHAR(100), orgUnitID VARCHAR(50), orgUnitName VARCHAR(100), PRIMARY KEY tid(org_importid), KEY orgUnitID (orgUnitID))SELECT * ...... FROM ..... ;
ImportskriptsgenereringsskriptSELECT CONCAT('\n-- ', `TABLE_NAME` , '\n''INSERT INTO ', `TABLE_SCHEMA` , '.', `TABLE_NAME` , '\n\nSELECT \n\t\'\' AS ', GROUP_CONCAT(COLUMN_NAME ORDER BY ORDINAL_POSITION SEPARATOR ', \n\t\'\' AS ' ), '\nFROM ', `TABLE_SCHEMA` , '.', `TABLE_NAME` , '\n; \n' ) AS createstatement FROM information_schema.COLUMNS -- sett inn navn på database som skal WHERE TABLE_SCHEMA IN ('drupal') -- sett inn liste over tabeller det skal lages skript for AND TABLE_NAME IN ('node', 'node_revisions', 'url_alias') GROUP BY TABLE_NAME;
Eksporter outputten som tekst Export -> CSV -> ingen skilletegn. Redigeres i teksteditor.