Lege velden vervangen in alle tabellen (MySQL)

Uit De Vliegende Brigade
Versie door Jeroen Strompf (overleg | bijdragen) op 22 jan 2016 om 19:25
(wijz) ← Oudere versie | Huidige versie (wijz) | Nieuwere versie → (wijz)
Naar navigatie springen Naar zoeken springen

Als ik de inhoud van een tabel exporteer naar een bestand, worden in alle rijden de velden met de null-waarde voorzien van een waarde \N. Dat wil ik niet, en ik kan dat ook niet zomaar aanpassen. Maar met een vernuftige sproc is dit allemaal te regelen...

Beoogd eindresultaat

Ik wil een dynamisch SQL-statement vormen (en uitvoeren!) dat lijkt op:

update tbl_export set veld01=ifnull(veld01,""), veld02=ifnull(veld02,""), ... , veldyz=ifnull(veldyz,"");

Daarbij weet ik vantevoren niet de namen van de kolommen, want die tabel wordt dynamisch aangemaakt. En liefst is ook de naam van de tabel dynamisch. Ik weet wel dat er geen selectiecriterium vereist is.

Fetch de namen van alle kolommen

De namen van alle kolommen kun je eenvoudig opvragen:

select column_name from information_schema.columns where table_schema='webwinkels' and table_name='tbl_export';

Omdat ik die namen in een sproc wil omfietsen tot iets executeerbaars, is een variant met group_concat handiger:

select group_concat(column_name) from information_schema.columns where table_schema='webwinkels' and table_name='tbl_export';

en omdat ik in het herhalende gedeelte van het statement, twee keer dezelfde kolomnaam nodig heb:

select group_concat(column_name,"=ifnull(",column_name,",'')") from information_schema.columns where table_schema='webwinkels' and table_name='tbl_export';

Resultaat

Deze code doet wat de bedoeling is! Het kan ongetwijfeld efficiënter, maar het gaat er primair om, dat-ie 't doet:

CREATE DEFINER=`root`@`localhost` PROCEDURE `ExportFixNull`(in tblname tinytext )
BEGIN

set @ddl1=concat
(
	"set @ddl2=(select group_concat(column_name, '=ifnull(',column_name,',XXX)') from information_schema.columns where table_schema='webwinkels' and table_name='"
	,
	tblname
	,
	"')"
);

prepare stmt from @ddl1;
execute stmt;

set @ddl3=concat
(
	"update ",
	tblname,
	" set ",
	replace(@ddl2,"XXX","''"),
	";"
);

prepare stmt from @ddl3;
execute stmt;