Toon posts:

[MySQL] ALTER TABLE IF NOT EXIST maar dan met rijen

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Goedendag,

Ik zit met een beetje een probleem.

Heb een leuk PHP script geschreven dat al een leuke groep gebruikers kent inmiddels.
Het maakt gebruik van MySQL.

Nu ben ik inmiddels alweer bij versie 2.x terwijl die van de meeste mensen die het gebruiken nog bij versie 1.x zitten.

Het grote verschil zit hem uiteraard in functies en onder de motorkap kun je het vinden met de grote hoeveelheid toegevoegde code en MySQL databases.

Maar ook de tabellen onderling verschillen hevig. Hoewel de structuur nog wel hetzelfde is zijn er wel nieuwe rijen toegevoegd.

Bijvoorbeeld

versie 1.x
code:
1
2
3
4
5
6
7
CREATE TABLE `fotos` (
  `fid` int(5) NOT NULL auto_increment,
  `albumnaam` varchar(255) NOT NULL,
  `naam` varchar(255) NOT NULL,
  `bestand` varchar(255) NOT NULL,
  PRIMARY KEY  (`fid`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;


versie 2.x
code:
1
2
3
4
5
6
7
8
9
CREATE TABLE `fotos` (
  `fid` int(5) NOT NULL auto_increment,
  `albumnaam` varchar(255) NOT NULL,
  `fotoorder` int(5) NOT NULL,
  `naam` varchar(255) NOT NULL,
  `info` text NOT NULL,
  `bestand` varchar(255) NOT NULL,
  PRIMARY KEY  (`fid`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=0;


Nu vraag ik me af, hoe kan ik snel alles updaten zonder alle gegevens weg te gooien.
Is er een mogelijkheid om alle rijen te updaten zodra die nog niet bestaan?

Je kan voor tabellen wel doen
code:
1
CREATE TABLE IF NOT EXISTS `fotos`


Maar ik heb Gegoogled en op GOT gezocht en gezocht maar het nergens voor rijen gevonden :?

Weet iemand misschien of hier een "truuc" voor is?
Want om overal met de hand
code:
1
ALTER TABLE `album` ADD `locatie` VARCHAR( 255 ) NOT NULL ;
toe te gaan voegen als je al 60 tabellen hebt is niet leuk als je het bij meer dan 10 man moet doen.:(

[ Voor 5% gewijzigd door Verwijderd op 06-12-2008 17:15 ]


Acties:
  • 0 Henk 'm!

Verwijderd

DESCRIBE `tabelnaam` gebruiken en de rest met PHP 'patches' oplossen. Er is nu eenmaal geen standaardoplossing voor.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:20
Rijen ? Je hebt geen nieuwe rijen, maar kolommen.

Wat je moet doen, is een SQL script maken waarin alle statements staan waarmee je van versie 1 naar 2 kunt upgraden.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Een NOT NULL constraint bij een wijziging op een tabel die data bevat, is niet handig. Je weet nu al dat je hier een error op gaat krijgen, men heeft nooit een waarde kunnen opgeven (kolom bestond niet) en zal dus een NULL zijn.

Bij je conversie-programma zul je dus eerst de nieuwe kolom moeten aanmaken, dan gewenste (default?) waardes opgeven en daarna pas de NOT NULL constraint moeten aanmaken. Of accepteren dat NULL is toegestaan.

Acties:
  • 0 Henk 'm!

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

Of een DEFAULT opgeven.

Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Verwijderd schreef op zaterdag 06 december 2008 @ 17:12:
Weet iemand misschien of hier een "truuc" voor is?
Want om overal met de hand
code:
1
ALTER TABLE `album` ADD `locatie` VARCHAR( 255 ) NOT NULL ;
toe te gaan voegen als je al 60 tabellen hebt is niet leuk als je het bij meer dan 10 man moet doen.:(
Waarom is dat een probleem? Er zijn honderden veelgebruikte producten die af en toe database-aanpassingen doen, door een script mee te leveren en de gebruiker "update.php" te laten uitvoeren na het uploaden van de nieuwe versie. Wel even zorgen dat de nieuwe versie het detecteert als de database nog niet geupdate is, zodat de gebruiker de data niet per ongeluk om zeep kan helpen.

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Moet ik het "bij meer dan 10" zien als losstaande versies die ze zelf draaien of als elke user heeft zelf eigen tabellen :? Dat laatste zou namelijk al een enorme flaw zijn zegmaar. Hopelijk lees ik het verkeerd.

En wat Confusion al zegt: er is niets mis met een update script. Daar 1 keer je queries in zetten en vervolgens draai je overal waar nodig dat scriptje om de structuur gelijk te trekken.

Acties:
  • 0 Henk 'm!

  • Schonhose
  • Registratie: April 2000
  • Laatst online: 17-09 20:01

Schonhose

Retro Icoon

Aangezien de nieuwe velden geen NULL mogen bevatten zou ik inderdaad een DEFAULT meegeven.
als je al 60 tabellen hebt ...
Ik mag toch serieus hopen dat je rijen bedoeld hier. Als dat zo is, dan is het geen probleem. Er komt gewoon een kolom bij en er wordt een DEFAULT waarde voor elke rij weggeschreven. Kost je maar een fractie van een seconde.

Als je wel tabellen bedoeld dan ben ik zeer benieuwd hoe je dit opgezet hebt. :+

Overigens: wat als ik geen locatie wil invullen? Wat is dan de waarde die opgeslagen wordt in de DB (i.i.g. geen NULL)? Hint: gebruik dat als DEFAULT. ;)

[ Voor 7% gewijzigd door Schonhose op 08-12-2008 12:19 ]

"The thing under my bed waiting to grab my ankle isn't real. I know that, and I also know that if I'm careful to keep my foot under the covers, it will never be able to grab my ankle." - Stephen King
Quinta: 3 januari 2005


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Aangezien de nieuwe velden geen NULL mogen bevatten zou ik inderdaad een DEFAULT meegeven.
Dat is redelijk zinloos, DEFAULT en NOT NULL zijn tegenstrijdig.

1) "kolom mag niet leeg zijn, er moet een waarde worden opgegeven"
2) "mocht er geen waarde zijn opgegeven, wat volgens regel 1 niet kan en mag voorkomen, gebruik dan de default waarde"

Wanneer je een NOT NULL wilt afdwingen, kun je onmogelijk een default gebruiken. Bij een conversie-slag, kun je wel eerst de nieuwe kolom aanmaken zónder constraint, dan t.b.v. de conversie een default waarde opgeven en vervolgens een NOT NULL-constraint toevoegen. Maar ga nooit een NOT NULL en een DEFAULT combineren, daarmee sla je de plank goed mis. Gebruik dan uitsluitend een DEFAULT, dan heb je blijkbaar ook datgene wat je wilt bereiken.

Acties:
  • 0 Henk 'm!

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

1) vind ik een loos argument. Maak er "kolom mag geen lege waarde hebben" van.

Acties:
  • 0 Henk 'm!

  • user109731
  • Registratie: Maart 2004
  • Niet online
Met BalusC, voor een boolean veld bijvoorbeeld kan het soms handig zijn om 'm NOT NULL te maken en standaard op False te zetten. Hoeft je programma geen rekening te houden met NULL-waarden en weet je zeker dat er altijd een boolean instaat :)

Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Een lege string '' is niet NULL en zal dus worden toegestaan. NULL is heel wat anders dan een lege string. Vaak heb je dan ook meer aan een CHECK-constraint die zowel op een lege string als een NULL-waarde controleert. MySQL ondersteunt dit echter niet, kent geen CHECK-constraints. Je zou eens naar PostgreSQL kunnen kijken, die kent dat wel.

Met een boolean kun je NULL, FALSE of TRUE krijgen. Een NOT NULL constraint kan dan bijzonder handig zijn wanneer je een keuze wilt afdwingen.

Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

cariolive23 schreef op maandag 08 december 2008 @ 18:22:
Dat is redelijk zinloos, DEFAULT en NOT NULL zijn tegenstrijdig.
cariolive23 schreef op maandag 08 december 2008 @ 20:00:
Met een boolean kun je NULL, FALSE of TRUE krijgen. Een NOT NULL constraint kan dan bijzonder handig zijn wanneer je een keuze wilt afdwingen.
Kortom, de DEFAULT en NOT NULL clauses vullen elkaar juist aan, in tegenstelling tot wat je eerste zei?

Bij het toevoegen van een NOT NULL kolom aan een bestaande database hanteert ik vaak het principe dat ik de kolom aanmaak met een NOT NULL DEFAULT 'sane default' en vervolgens de DEFAULT weer verwijder. Die dient alleen voor de initialisatie. Een alternatief is natuurlijk: de kolom toevoegen, de waarde overal zetten en dan de not null constraint toevoegen. Het eerste is wat veiliger als de database in productie is, omdat rijen die in de tussentijd toegevoegd worden dan in ieder geval ook die default krijgen.

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

cariolive23 schreef op maandag 08 december 2008 @ 20:00:
Een lege string '' is niet NULL en zal dus worden toegestaan.
So? Wat is het verschil met de bestaande NOT NULL kolommen? Kun je daar geen lege strings invoeren? 8)7 Met een lege waarde bedoel ik niet een lege string ofzo, gewoon iets dat null is :)

[ Voor 4% gewijzigd door BalusC op 09-12-2008 00:01 ]


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
cariolive23 schreef op maandag 08 december 2008 @ 20:00:
Een lege string '' is niet NULL en zal dus worden toegestaan. NULL is heel wat anders dan een lege string.
Niet alle DBMSen zijn het daarmee eens volgens mij. Ik weet iig dat LLBLGen een null value converteert naar een String.Empty voor tekst-velden. Volgens een collega had dat met DB-compatibiliteit te maken.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Grijze Vos schreef op dinsdag 09 december 2008 @ 16:53:
[...]
Niet alle DBMSen zijn het daarmee eens volgens mij. Ik weet iig dat LLBLGen een null value converteert naar een String.Empty voor tekst-velden. Volgens een collega had dat met DB-compatibiliteit te maken.
Toch is het natuurlijk wat compleet anders. Ik zou het ook gek vinden als LLBLGen dat als enige optie heeft. Soms zou je best verschil willen maken tussen String.Empty en NULL

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
cariolive23 schreef op maandag 08 december 2008 @ 18:22:
[...]
Dat is redelijk zinloos, DEFAULT en NOT NULL zijn tegenstrijdig.

1) "kolom mag niet leeg zijn, er moet een waarde worden opgegeven"
2) "mocht er geen waarde zijn opgegeven, wat volgens regel 1 niet kan en mag voorkomen, gebruik dan de default waarde"

Wanneer je een NOT NULL wilt afdwingen, kun je onmogelijk een default gebruiken. Bij een conversie-slag, kun je wel eerst de nieuwe kolom aanmaken zónder constraint, dan t.b.v. de conversie een default waarde opgeven en vervolgens een NOT NULL-constraint toevoegen. Maar ga nooit een NOT NULL en een DEFAULT combineren, daarmee sla je de plank goed mis. Gebruik dan uitsluitend een DEFAULT, dan heb je blijkbaar ook datgene wat je wilt bereiken.
Onzin. Je kan prima DEFAULT en NOT NULL combineren. Een DEFAULT geeft alleen aan dat bij een INSERT waarbij de betreffende kolom niet expliciet een waarde krijgt de default wordt gebruikt. Ik mag echter als ik alleen een DEFAULT gebruik prima een expliciete NULL toekennen aan de betreffende kolom via een INSERT of UPDATE, dat mag echter niet als ik ook een NOT NULL meegeef.

Als ik alleen een NOT NULL gebruik, dan zal ik bij een INSERT de kolom altijd expliciet een waarde moeten geven, maar mag hij geen NULL zijn.

In andere woorden DEFAULT en NOT NULL zijn niet tegenstrijdig, maar juist complementair.
Confusion schreef op maandag 08 december 2008 @ 20:58:
Bij het toevoegen van een NOT NULL kolom aan een bestaande database hanteert ik vaak het principe dat ik de kolom aanmaak met een NOT NULL DEFAULT 'sane default' en vervolgens de DEFAULT weer verwijder. Die dient alleen voor de initialisatie. Een alternatief is natuurlijk: de kolom toevoegen, de waarde overal zetten en dan de not null constraint toevoegen. Het eerste is wat veiliger als de database in productie is, omdat rijen die in de tussentijd toegevoegd worden dan in ieder geval ook die default krijgen.
Ligt heel erg aan je DBMS, sommige DBMSen gebruiken een DEFAULT echt alleen bij INSERT, bij een ALTER TABLE wordt de default dan niet toegekend aan bestaande records waarbij de gewijzigde kolom een default krijgt..

[ Voor 22% gewijzigd door Remus op 09-12-2008 18:42 ]


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Even een hele andere insteek, maar waarom hernoem je niet de originele tabel (versie 1.x), maak je dan de nieuwe tabel aan en via een insert into select query kopieer je vervolgens alle data terug.

En in jouw geval dien je even te controleren of de query 'select fotoorder from fotos limit 1' geen fouten oplevert. Geen fouten, dan mag je er vanuit gaan dat de database up-to-date is. Krijg je wel een fout, dan maakt de gebruiker nog gebruik van het 1.x database model en kun je de migratie starten.

Oh, en vergeet niet alle statements binnen dezelfde transactie uit te voeren. Mocht er iets fout gaan, dan blijft de gebruiker niet met een half gemigreerde database zitten.

If it isn't broken, fix it until it is..

Pagina: 1