Variabelen (MySQL): verschil tussen versies

Uit De Vliegende Brigade
Naar navigatie springen Naar zoeken springen
 
(15 tussenliggende versies door dezelfde gebruiker niet weergegeven)
Regel 1: Regel 1:
Ook buiten ''sprocs'' kun je met variabelen hobbyen. Bv.:
+
* In gewone SQL-scripts kun je variabelen gebruiken, zij het met beperkingen
 +
* In sprocs zijn er minder beperkingen
 +
* Variabelen hoeven niet vantevoren te worden gedeclareerd.
 +
 
 +
== Voorbeeld: Set & select een variabele ==
  
 
  set @aanbod = true;
 
  set @aanbod = true;
 
  select @aanbod;
 
  select @aanbod;
 
  1
 
  1
 +
 +
Meerdere variabelen kun je in één keer zetten:
 +
 +
<pre>
 +
set
 +
    @a=1,
 +
    @b=2;
 +
   
 +
select @a;
 +
select @b;
 +
</pre>
 +
 +
== Voorbeeld: Output van een query naar een variabele ==
 +
 +
''' INTO '''
 +
 +
select into @var1 count(*) from tbl_root;
 +
 +
''' Iets met haakjes '''
  
 
Om de ééndimensionale output van een query aan een variabele toe te wijzen, moet je haakjes om de query gebruiken, met de punk-komma ''buiten'' het sluithaakje:
 
Om de ééndimensionale output van een query aan een variabele toe te wijzen, moet je haakjes om de query gebruiken, met de punk-komma ''buiten'' het sluithaakje:
Regel 9: Regel 32:
 
  set @ouder=(select tid from term_data where name = "DeWalt" and description = "Koolborstels voor DeWalt");
 
  set @ouder=(select tid from term_data where name = "DeWalt" and description = "Koolborstels voor DeWalt");
  
== Input-argumenten bij sprocs ==
+
''' Exotisch '''
 +
 
 +
Eén van de bronnen hieronder komt echter met hele andere syntaxis, waarbij de crux is dat de variabele ''binnen'' het select-statement gebracht moet worden:
 +
 
 +
<pre>
 +
SET @user := 123456;
 +
SELECT @group := `group` FROM user WHERE user = @user;
 +
SELECT * FROM user WHERE `group` = @group;
 +
</pre>
 +
 
 +
== Voorbeeld: Variabele in where-clause ==
  
Een input-argument (of hoe dat moge heten) in een sproc, heeft geen '@' nodig, maar er zijn wel beperkingen:
+
Wellicht is de regel, dat je altijd een variabele kunt gebruiken waar je anders een waarde uit een tabel zou gebruiken. In dit voorbeeld gaat die analogie in ieder geval op:
  
 
<pre>
 
<pre>
CREATE DEFINER=`root`@`localhost` PROCEDURE `ExportFixNull`(in tblname tinytext )
+
set @begin="2016-01-01";
 +
set @eind="2016-02-01";
 +
 
 +
select
 +
"koolborstels", 
 +
sum(order_total),
 +
count(*) from koolborstels.uc_orders         
 +
where
 +
order_status="Completed"
 +
and
 +
created >= unix_timestamp(@begin)
 +
and 
 +
created < unix_timestamp(@eind)
 +
</pre>
 +
 
 +
== Sprocs & input-variabelen ==
 +
 
 +
Input-variabelen in sprocs kun je als dynamische argumenten gebruiken in SQL-statements. Er zijn echter onduidelijke beperkingen: Variabelen mogen aan de rechterkant voorkomen in een vergelijking, maar ogenschijnlijk niet op andere plekken. Misschien zoals hiervoor al opgemerkt: Je kunt een variabele gebruiken op plekken waar anders sowieso een dynamische waarde zou hebben gestaan (dus alles wat bij compilatie nog niet bekend is):
 +
 
 +
<pre>
 +
CREATE DEFINER=`root`@`localhost` PROCEDURE `sprocs_en_variabelen`(in argument tinytext )
 
BEGIN
 
BEGIN
  
  select tblname;          -- Dit werkt!
+
   select * from argument;               -- Foutmelding dat tabel 'argument' niet bestaat
   select * from tblname;   -- Werk niet: Foutmelding dat tabel 'tblname' niet bestaan
+
   select * from @argument;             -- Syntax error
   select * from @tblname;   -- Syntax error
+
  select * from root where sku=argument -- OK
  
 
END
 
END
 
</pre>
 
</pre>
  
Wat hoe dan ook werkt: Een string samenstellen en executeren, werkt in ieder geval wel.
+
Een complexer voorbeeld:
 +
 
 +
<pre>
 +
CREATE DEFINER=`root`@`localhost` PROCEDURE `AddColumnUnlessExists`(
 +
    IN dbName tinytext,
 +
    IN tableName tinytext,
 +
    IN fieldName tinytext,
 +
    in fieldDef varchar(100)
 +
)
 +
begin
 +
IF NOT EXISTS (
 +
SELECT * FROM information_schema.COLUMNS
 +
WHERE column_name=fieldName
 +
and table_name=tableName
 +
and table_schema=dbName
 +
)
 +
THEN
 +
set @ddl=CONCAT('ALTER TABLE ',dbName,'.',tableName,
 +
' ADD COLUMN ',fieldName," ",fieldDef);
 +
prepare stmt from @ddl;
 +
execute stmt;
 +
 
 +
END IF;
 +
end
 +
</pre>
 +
 
 +
Een vergelijkbaar voorbeeld:
 +
 
 +
<pre>
 +
CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_column_names`(in tabelnaam tinytext)
 +
BEGIN
 +
set @ddl1=(select group_concat(column_name) from information_schema.columns where table_name=tabelnaam);
 +
select @ddl1;
 +
</pre>
 +
 
 +
== Zie ook ==
 +
 
 +
* [[Kolomnamen achterhalen (MySQL)]]
  
 
== Bronnen ==
 
== Bronnen ==
  
 
* https://dev.mysql.com/doc/refman/5.1/en/control-flow-functions.html
 
* https://dev.mysql.com/doc/refman/5.1/en/control-flow-functions.html
 +
* http://stackoverflow.com/questions/3888735/mysql-set-user-variable-from-result-of-query

Huidige versie van 25 sep 2019 om 10:53

  • In gewone SQL-scripts kun je variabelen gebruiken, zij het met beperkingen
  • In sprocs zijn er minder beperkingen
  • Variabelen hoeven niet vantevoren te worden gedeclareerd.

Voorbeeld: Set & select een variabele

set @aanbod = true;
select @aanbod;
1

Meerdere variabelen kun je in één keer zetten:

set 
    @a=1,
    @b=2;
    
select @a;
select @b;

Voorbeeld: Output van een query naar een variabele

INTO

select into @var1 count(*) from tbl_root;

Iets met haakjes

Om de ééndimensionale output van een query aan een variabele toe te wijzen, moet je haakjes om de query gebruiken, met de punk-komma buiten het sluithaakje:

set @ouder=(select tid from term_data where name = "DeWalt" and description = "Koolborstels voor DeWalt");

Exotisch

Eén van de bronnen hieronder komt echter met hele andere syntaxis, waarbij de crux is dat de variabele binnen het select-statement gebracht moet worden:

SET @user := 123456;
SELECT @group := `group` FROM user WHERE user = @user;
SELECT * FROM user WHERE `group` = @group;

Voorbeeld: Variabele in where-clause

Wellicht is de regel, dat je altijd een variabele kunt gebruiken waar je anders een waarde uit een tabel zou gebruiken. In dit voorbeeld gaat die analogie in ieder geval op:

set @begin="2016-01-01";
set @eind="2016-02-01";

select 
	"koolborstels",  
	sum(order_total),
	count(*) from koolborstels.uc_orders          
where 
	order_status="Completed" 
and 
	created >= unix_timestamp(@begin) 
and   
	created < unix_timestamp(@eind)

Sprocs & input-variabelen

Input-variabelen in sprocs kun je als dynamische argumenten gebruiken in SQL-statements. Er zijn echter onduidelijke beperkingen: Variabelen mogen aan de rechterkant voorkomen in een vergelijking, maar ogenschijnlijk niet op andere plekken. Misschien zoals hiervoor al opgemerkt: Je kunt een variabele gebruiken op plekken waar anders sowieso een dynamische waarde zou hebben gestaan (dus alles wat bij compilatie nog niet bekend is):

CREATE DEFINER=`root`@`localhost` PROCEDURE `sprocs_en_variabelen`(in argument tinytext )
BEGIN

   select * from argument;               -- Foutmelding dat tabel 'argument' niet bestaat
   select * from @argument;              -- Syntax error
   select * from root where sku=argument -- OK

END

Een complexer voorbeeld:

CREATE DEFINER=`root`@`localhost` PROCEDURE `AddColumnUnlessExists`(
    IN dbName tinytext,
    IN tableName tinytext,
    IN fieldName tinytext,
    in fieldDef varchar(100)
)
begin
	IF NOT EXISTS (
		SELECT * FROM information_schema.COLUMNS
		WHERE column_name=fieldName
		and table_name=tableName
		and table_schema=dbName
		)
	THEN
		set @ddl=CONCAT('ALTER TABLE ',dbName,'.',tableName,
			' ADD COLUMN ',fieldName," ",fieldDef);
		prepare stmt from @ddl;
		execute stmt;

	END IF;
end

Een vergelijkbaar voorbeeld:

CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_column_names`(in tabelnaam tinytext)
BEGIN
set @ddl1=(select group_concat(column_name) from information_schema.columns where table_name=tabelnaam);
select @ddl1;

Zie ook

Bronnen