mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 12:49:34 +00:00
93_DbRep: sqlCmd can handle SQL session variables, Forum:#96082
git-svn-id: https://svn.fhem.de/fhem/trunk@18345 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
58ac6be5dd
commit
a84b4b345f
@ -1,5 +1,6 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||||
# Do not insert empty lines here, update check depends on it.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
|
- feature: 93_DbRep: sqlCmd can handle SQL session variables, Forum:#96082
|
||||||
- bugfix: 98_DOIFtools: remove Log in DOIFtoolsNextTimer
|
- bugfix: 98_DOIFtools: remove Log in DOIFtoolsNextTimer
|
||||||
- bugfix: 93_DbRep: V8.9.10, fix warnings Malformed UTF-8 character during
|
- bugfix: 93_DbRep: V8.9.10, fix warnings Malformed UTF-8 character during
|
||||||
importFromFile, Forum:#96056
|
importFromFile, Forum:#96056
|
||||||
|
@ -57,6 +57,7 @@ no if $] >= 5.017011, warnings => 'experimental::smartmatch';
|
|||||||
|
|
||||||
# Versions History intern
|
# Versions History intern
|
||||||
our %DbRep_vNotesIntern = (
|
our %DbRep_vNotesIntern = (
|
||||||
|
"8.10.0" => "19.01.2019 sqlCmd, dbValue may input SQL session variables, Forum:#96082 ",
|
||||||
"8.9.10" => "18.01.2019 fix warnings Malformed UTF-8 character during importFromFile, Forum:#96056 ",
|
"8.9.10" => "18.01.2019 fix warnings Malformed UTF-8 character during importFromFile, Forum:#96056 ",
|
||||||
"8.9.9" => "06.01.2019 diffval_DoParse: 'ORDER BY TIMESTAMP' added to statements Forum:https://forum.fhem.de/index.php/topic,53584.msg882082.html#msg882082",
|
"8.9.9" => "06.01.2019 diffval_DoParse: 'ORDER BY TIMESTAMP' added to statements Forum:https://forum.fhem.de/index.php/topic,53584.msg882082.html#msg882082",
|
||||||
"8.9.8" => "27.11.2018 minor fix in deviceRename, commandref revised ",
|
"8.9.8" => "27.11.2018 minor fix in deviceRename, commandref revised ",
|
||||||
@ -130,6 +131,7 @@ our %DbRep_vNotesIntern = (
|
|||||||
|
|
||||||
# Versions History extern:
|
# Versions History extern:
|
||||||
our %DbRep_vNotesExtern = (
|
our %DbRep_vNotesExtern = (
|
||||||
|
"8.10.0" => "19.01.2019 In commands sqlCmd, dbValue you may now use SQL session variables like \"SET \@open:=NULL,\@closed:=NULL; SELECT ...\", Forum:#96082",
|
||||||
"8.9.0" => "07.11.2018 new command set delDoublets added. This command allows to delete multiple occuring identical records. ",
|
"8.9.0" => "07.11.2018 new command set delDoublets added. This command allows to delete multiple occuring identical records. ",
|
||||||
"8.8.0" => "06.11.2018 new attribute 'fastStart'. Usually every DbRep-device is making a short connect to its database when "
|
"8.8.0" => "06.11.2018 new attribute 'fastStart'. Usually every DbRep-device is making a short connect to its database when "
|
||||||
."FHEM is restarted. When this attribute is set, the initial connect is done when the DbRep-device is doing its "
|
."FHEM is restarted. When this attribute is set, the initial connect is done when the DbRep-device is doing its "
|
||||||
@ -944,7 +946,7 @@ sub DbRep_Get($@) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$i = 0;
|
$i = 0;
|
||||||
foreach my $key (reverse sort(keys %hs)) {
|
foreach my $key (sort{$b<=>$a}(keys %hs)) {
|
||||||
$val0 = $hs{$key};
|
$val0 = $hs{$key};
|
||||||
$ret .= sprintf("<td style=\"vertical-align:top\"><b>$key</b> </td><td style=\"vertical-align:top\">$val0</td>" );
|
$ret .= sprintf("<td style=\"vertical-align:top\"><b>$key</b> </td><td style=\"vertical-align:top\">$val0</td>" );
|
||||||
$ret .= "</tr>";
|
$ret .= "</tr>";
|
||||||
@ -969,7 +971,7 @@ sub DbRep_Get($@) {
|
|||||||
$ret .= "<tbody>";
|
$ret .= "<tbody>";
|
||||||
$ret .= "<tr class=\"even\">";
|
$ret .= "<tr class=\"even\">";
|
||||||
$i = 0;
|
$i = 0;
|
||||||
foreach my $key (reverse sort(keys %DbRep_vNotesExtern)) {
|
foreach my $key (sort{$b<=>$a}(keys %DbRep_vNotesExtern)) {
|
||||||
($val0,$val1) = split(/\s/,$DbRep_vNotesExtern{$key},2);
|
($val0,$val1) = split(/\s/,$DbRep_vNotesExtern{$key},2);
|
||||||
$ret .= sprintf("<td style=\"vertical-align:top\"><b>$key</b> </td><td style=\"vertical-align:top\">$val0 </td><td>$val1</td>" );
|
$ret .= sprintf("<td style=\"vertical-align:top\"><b>$key</b> </td><td style=\"vertical-align:top\">$val0 </td><td>$val1</td>" );
|
||||||
$ret .= "</tr>";
|
$ret .= "</tr>";
|
||||||
@ -5559,12 +5561,31 @@ sub sqlCmd_DoParse($) {
|
|||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
|
|
||||||
my $sql = ($cmd =~ m/\;$/)?$cmd:$cmd.";";
|
my $sql = ($cmd =~ m/\;$/)?$cmd:$cmd.";";
|
||||||
|
|
||||||
|
# split SQL-Parameter Statement falls mitgegeben
|
||||||
|
# z.B. SET @open:=NULL, @closed:=NULL; Select ...
|
||||||
|
my $set;
|
||||||
|
if($cmd =~ /^SET.*;/i) {
|
||||||
|
$cmd =~ m/^(SET.*?;)(.*)/i;
|
||||||
|
$set = $1;
|
||||||
|
$sql = $2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($set) {
|
||||||
|
Log3($name, 4, "DbRep $name - Set SQL session variables: $set");
|
||||||
|
eval {$dbh->do($set);}; # @\RB = Resetbit wenn neues Selektionsintervall beginnt
|
||||||
|
}
|
||||||
|
if ($@) {
|
||||||
|
$err = encode_base64($@,"");
|
||||||
|
Log3 ($name, 2, "DbRep $name - ERROR - $@");
|
||||||
|
$dbh->disconnect;
|
||||||
|
return "$name|''|$opt|$set|''|''|$err";
|
||||||
|
}
|
||||||
|
|
||||||
# Allow inplace replacement of keywords for timings (use time attribute syntax)
|
# Allow inplace replacement of keywords for timings (use time attribute syntax)
|
||||||
$sql =~ s/§timestamp_begin§/'$runtime_string_first'/g;
|
$sql =~ s/§timestamp_begin§/'$runtime_string_first'/g;
|
||||||
$sql =~ s/§timestamp_end§/'$runtime_string_next'/g;
|
$sql =~ s/§timestamp_end§/'$runtime_string_next'/g;
|
||||||
|
|
||||||
# Debug "SQL :".$sql.":";
|
|
||||||
|
|
||||||
Log3($name, 4, "DbRep $name - SQL execute: $sql");
|
Log3($name, 4, "DbRep $name - SQL execute: $sql");
|
||||||
|
|
||||||
# SQL-Startzeit
|
# SQL-Startzeit
|
||||||
@ -5577,7 +5598,6 @@ sub sqlCmd_DoParse($) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if ($@) {
|
if ($@) {
|
||||||
# error bei sql-execute
|
|
||||||
$err = encode_base64($@,"");
|
$err = encode_base64($@,"");
|
||||||
Log3 ($name, 2, "DbRep $name - ERROR - $@");
|
Log3 ($name, 2, "DbRep $name - ERROR - $@");
|
||||||
$dbh->disconnect;
|
$dbh->disconnect;
|
||||||
@ -5629,7 +5649,7 @@ sub sqlCmd_DoParse($) {
|
|||||||
|
|
||||||
$rt = $rt.",".$brt;
|
$rt = $rt.",".$brt;
|
||||||
|
|
||||||
return "$name|$rowstring|$opt|$sql|$nrows|$rt|$err";
|
return "$name|$rowstring|$opt|$cmd|$nrows|$rt|$err";
|
||||||
}
|
}
|
||||||
|
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
@ -9954,6 +9974,27 @@ sub DbRep_dbValue($$) {
|
|||||||
Log3 ($name, 4, "DbRep $name - Command: dbValue");
|
Log3 ($name, 4, "DbRep $name - Command: dbValue");
|
||||||
Log3 ($name, 4, "DbRep $name - SQL execute: $sql");
|
Log3 ($name, 4, "DbRep $name - SQL execute: $sql");
|
||||||
|
|
||||||
|
# split SQL-Parameter Statement falls mitgegeben
|
||||||
|
# z.B. SET @open:=NULL, @closed:=NULL; Select ...
|
||||||
|
my $set;
|
||||||
|
if($cmd =~ /^SET.*;/i) {
|
||||||
|
$cmd =~ m/^(SET.*?;)(.*)/i;
|
||||||
|
$set = $1;
|
||||||
|
$sql = $2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($set) {
|
||||||
|
Log3($name, 4, "DbRep $name - Set SQL session variables: $set");
|
||||||
|
eval {$dbh->do($set);}; # @\RB = Resetbit wenn neues Selektionsintervall beginnt
|
||||||
|
}
|
||||||
|
if ($@) {
|
||||||
|
$err = $@;
|
||||||
|
Log3 ($name, 2, "DbRep $name - $err");
|
||||||
|
ReadingsSingleUpdateValue ($hash, "errortext", $err, 1);
|
||||||
|
ReadingsSingleUpdateValue ($hash, "state", "error", 1);
|
||||||
|
return ($err);
|
||||||
|
}
|
||||||
|
|
||||||
# SQL-Startzeit
|
# SQL-Startzeit
|
||||||
my $st = [gettimeofday];
|
my $st = [gettimeofday];
|
||||||
|
|
||||||
@ -11294,6 +11335,8 @@ return;
|
|||||||
"allowDeletion" has to be set for security reason. <br>
|
"allowDeletion" has to be set for security reason. <br>
|
||||||
The statement doesn't consider limitations by attributes "device", "reading", "time.*"
|
The statement doesn't consider limitations by attributes "device", "reading", "time.*"
|
||||||
respectively "aggregation". <br>
|
respectively "aggregation". <br>
|
||||||
|
This command also accept the setting of SQL session variables like "SET @open:=NULL,
|
||||||
|
@closed:=NULL;". <br>
|
||||||
If the <a href="#DbRepattr">attribute</a> "timestamp_begin" respectively "timestamp_end"
|
If the <a href="#DbRepattr">attribute</a> "timestamp_begin" respectively "timestamp_end"
|
||||||
is assumed in the statement, it is possible to use placeholder "<b>§timestamp_begin§</b>" respectively
|
is assumed in the statement, it is possible to use placeholder "<b>§timestamp_begin§</b>" respectively
|
||||||
"<b>§timestamp_end§</b>" on suitable place. <br><br>
|
"<b>§timestamp_end§</b>" on suitable place. <br><br>
|
||||||
@ -11319,6 +11362,25 @@ return;
|
|||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
Here you can see an example of a more complex statement (MySQL) with setting SQL session
|
||||||
|
variables: <br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>set <name> sqlCmd SET @open:=NULL, @closed:=NULL;
|
||||||
|
SELECT
|
||||||
|
TIMESTAMP, VALUE,DEVICE,
|
||||||
|
@open AS open,
|
||||||
|
@open := IF(VALUE = 'open', TIMESTAMP, NULL) AS curr_open,
|
||||||
|
@closed := IF(VALUE = 'closed', TIMESTAMP, NULL) AS closed
|
||||||
|
FROM history WHERE
|
||||||
|
DATE(TIMESTAMP) = CURDATE() AND
|
||||||
|
DEVICE = "HT_Fensterkontakt" AND
|
||||||
|
READING = "state" AND
|
||||||
|
(VALUE = "open" OR VALUE = "closed")
|
||||||
|
ORDER BY TIMESTAMP; </li>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
|
||||||
The result of the statement will be shown in <a href="#DbRepReadings">Reading</a> "SqlResult".
|
The result of the statement will be shown in <a href="#DbRepReadings">Reading</a> "SqlResult".
|
||||||
The formatting of result can be choosen by <a href="#DbRepattr">attribute</a> "sqlResultFormat", as well as the used
|
The formatting of result can be choosen by <a href="#DbRepattr">attribute</a> "sqlResultFormat", as well as the used
|
||||||
field separator can be determined by <a href="#DbRepattr">attribute</a> "sqlResultFieldSep". <br><br>
|
field separator can be determined by <a href="#DbRepattr">attribute</a> "sqlResultFieldSep". <br><br>
|
||||||
@ -11531,6 +11593,8 @@ return;
|
|||||||
Executes the specified SQL-statement in <b>blocking</b> manner. Because of its mode of operation
|
Executes the specified SQL-statement in <b>blocking</b> manner. Because of its mode of operation
|
||||||
this function is particular convenient for user own perl scripts. <br>
|
this function is particular convenient for user own perl scripts. <br>
|
||||||
The input accepts multi line commands and delivers multi line results as well.
|
The input accepts multi line commands and delivers multi line results as well.
|
||||||
|
This command also accept the setting of SQL session variables like "SET @open:=NULL,
|
||||||
|
@closed:=NULL;". <br>
|
||||||
If several fields are selected and passed back, the fieds are separated by the separator defined
|
If several fields are selected and passed back, the fieds are separated by the separator defined
|
||||||
by <a href="#DbRepattr">attribute</a> "sqlResultFieldSep" (default "|"). Several result lines
|
by <a href="#DbRepattr">attribute</a> "sqlResultFieldSep" (default "|"). Several result lines
|
||||||
are separated by newline ("\n"). <br>
|
are separated by newline ("\n"). <br>
|
||||||
@ -13604,6 +13668,8 @@ sub bdump {
|
|||||||
<a href="#DbRepattr">Attribut</a> "allowDeletion" gesetzt sein. <br>
|
<a href="#DbRepattr">Attribut</a> "allowDeletion" gesetzt sein. <br>
|
||||||
Bei der Ausführung dieses Kommandos werden keine Einschränkungen durch gesetzte Attribute
|
Bei der Ausführung dieses Kommandos werden keine Einschränkungen durch gesetzte Attribute
|
||||||
"device", "reading", "time.*" bzw. "aggregation" berücksichtigt. <br>
|
"device", "reading", "time.*" bzw. "aggregation" berücksichtigt. <br>
|
||||||
|
Dieses Kommando akzeptiert ebenfalls das Setzen von SQL Session Variablen wie z.B.
|
||||||
|
"SET @open:=NULL, @closed:=NULL;". <br>
|
||||||
Sollen die im Modul gesetzten <a href="#DbRepattr">Attribute</a> "timestamp_begin" bzw.
|
Sollen die im Modul gesetzten <a href="#DbRepattr">Attribute</a> "timestamp_begin" bzw.
|
||||||
"timestamp_end" im Statement berücksichtigt werden, können die Platzhalter
|
"timestamp_end" im Statement berücksichtigt werden, können die Platzhalter
|
||||||
"<b>§timestamp_begin§</b>" bzw. "<b>§timestamp_end§</b>" dafür verwendet werden. <br><br>
|
"<b>§timestamp_begin§</b>" bzw. "<b>§timestamp_end§</b>" dafür verwendet werden. <br><br>
|
||||||
@ -13629,6 +13695,25 @@ sub bdump {
|
|||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
Nachfolgend noch ein Beispiel für ein komplexeres Statement (MySQL) unter Mitgabe von
|
||||||
|
SQL Session Variablen: <br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>set <name> sqlCmd SET @open:=NULL, @closed:=NULL;
|
||||||
|
SELECT
|
||||||
|
TIMESTAMP, VALUE,DEVICE,
|
||||||
|
@open AS open,
|
||||||
|
@open := IF(VALUE = 'open', TIMESTAMP, NULL) AS curr_open,
|
||||||
|
@closed := IF(VALUE = 'closed', TIMESTAMP, NULL) AS closed
|
||||||
|
FROM history WHERE
|
||||||
|
DATE(TIMESTAMP) = CURDATE() AND
|
||||||
|
DEVICE = "HT_Fensterkontakt" AND
|
||||||
|
READING = "state" AND
|
||||||
|
(VALUE = "open" OR VALUE = "closed")
|
||||||
|
ORDER BY TIMESTAMP; </li>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
|
||||||
Das Ergebnis des Statements wird im <a href="#DbRepReadings">Reading</a> "SqlResult" dargestellt.
|
Das Ergebnis des Statements wird im <a href="#DbRepReadings">Reading</a> "SqlResult" dargestellt.
|
||||||
Die Ergebnis-Formatierung kann durch das <a href="#DbRepattr">Attribut</a> "sqlResultFormat" ausgewählt, sowie der verwendete
|
Die Ergebnis-Formatierung kann durch das <a href="#DbRepattr">Attribut</a> "sqlResultFormat" ausgewählt, sowie der verwendete
|
||||||
Feldtrenner durch das <a href="#DbRepattr">Attribut</a> "sqlResultFieldSep" festgelegt werden. <br><br>
|
Feldtrenner durch das <a href="#DbRepattr">Attribut</a> "sqlResultFieldSep" festgelegt werden. <br><br>
|
||||||
@ -13849,6 +13934,8 @@ sub bdump {
|
|||||||
Führt das angegebene SQL-Statement <b>blockierend</b> aus. Diese Funktion ist durch ihre Arbeitsweise
|
Führt das angegebene SQL-Statement <b>blockierend</b> aus. Diese Funktion ist durch ihre Arbeitsweise
|
||||||
speziell für den Einsatz in benutzerspezifischen Scripten geeignet. <br>
|
speziell für den Einsatz in benutzerspezifischen Scripten geeignet. <br>
|
||||||
Die Eingabe akzeptiert Mehrzeiler und gibt ebenso mehrzeilige Ergebisse zurück.
|
Die Eingabe akzeptiert Mehrzeiler und gibt ebenso mehrzeilige Ergebisse zurück.
|
||||||
|
Dieses Kommando akzeptiert ebenfalls das Setzen von SQL Session Variablen wie z.B.
|
||||||
|
"SET @open:=NULL, @closed:=NULL;". <br>
|
||||||
Werden mehrere Felder selektiert und zurückgegeben, erfolgt die Feldtrennung mit dem Trenner
|
Werden mehrere Felder selektiert und zurückgegeben, erfolgt die Feldtrennung mit dem Trenner
|
||||||
des <a href="#DbRepattr">Attributes</a> "sqlResultFieldSep" (default "|"). Mehrere Ergebniszeilen
|
des <a href="#DbRepattr">Attributes</a> "sqlResultFieldSep" (default "|"). Mehrere Ergebniszeilen
|
||||||
werden mit Newline ("\n") separiert. <br>
|
werden mit Newline ("\n") separiert. <br>
|
||||||
|
Loading…
Reference in New Issue
Block a user