I have a SET variables followed by a SELECT which works fine with MySQL until I attempt this wrapped in a Java query sql:query (which then indicates a syntax error on `SET). I removed the chevrons around the sql:query statement so you can see it.
sql:query var="queryresults" dataSource="jdbc/logs"
SET #locationID=0, #ts=NULL, #changed=0;
SELECT
L4.assetid, etc etc
Is there a different command to SET variables for sql:query or do I need to set these variables beforehand, outside of sql:query?
Related
Playing around with MariaDB I accidentally found out that it's possible to use # without giving a variable name. I executed following statement:
SELECT # INTO #;
I would have expected a syntax error since the variable name was omitted, but instead it executes just fine. Now I'm wondering what is happening.
How does MariaDB interpret the # symbol in this case? What does this SELECT actually do? Or is it just completely ignored without any further operation?
Although neither the MySQL nor MariaDB documentation specifically mentions it, apparently user-defined variable are allowed to have an empty name. # is the same as #'', and it's treated just like any other variable.
So
SELECT # INTO #;
is like
SELECT #myvar INTO #myvar;
It's a useless statement, since it's just assigning a variable to itself, equivalent to
SET # = #;
This question already has answers here:
MySQL: #variable vs. variable. What's the difference?
(5 answers)
Closed 2 years ago.
I am trying to learn MySQL and after doing some database, I am having the following questions.
When declaring a variable inside a procedure or in the function I can do it like this:
using # sign, like this: SET #varname = varcontent
using DECLARE keyword, like this: DECLARE varname vartype
using directly SET without DECLARE, like this SET varname = varcontent
My doubts are:
what type of syntax is correct, using DECLARE, # or SET?
what would be the correct form of doing it?
Also, I would like if you could recommend some good practices with MySQL.
varname and #varname are two DIFFERENT variables!
#varname - user-defined variable.
Exists always. Even when it was not initialized and/or used, in such case it has NULL value. I.e. it does not need in declaration.
Have no datatype (or it has dynamic datatype). Datatype may be easily changed by assigning the value of another datatype.
This variable has a scope of a connection. I.e. it exists until the connection exists, and its value is not altered until it is altered explicitly. Each connection has its own variavle with the same name, they do not interfere.
For example, you may set it to some value, then use/alter this value in called stored procedure, then use the value altered in the procedure in outer code after the procedure finished.
varname - local (declared) variable
Not exists in anonymous code, exists only within compound (BEGIN-END) code block. Must be declared explicitly at the beginning of the block. Is destroyed at the end of the block. Special type of local variable is function/procedure parameter - it is declared in function/procedure header and exists within the function/procedure code block.
Has definite datatype. Cannot be re-declared.
Has a scope of a block where it is defined.
If a variable and a column with the same name exists in some scope, then the variable has priority and masks the column, so if you need to access the column you must specify table alias.
In most constructions any variable type may be used. But sometimes only one of types may be used - consult User Manual.
1.using # like set #varname= varcontent
This statement initializes user-defined variable with some value.
2.using declare like declare varname vartype
This statement declares local variable. May posess at the beginning of BEGIN-END block. Does not set a value to the variable (it is NULL).
3.using directly set varname=varcontent without declare
Causes an error.
I am using classic ASP and MySQL (using PHP wouldn't change the point of the question).
I need to set a variable over my homepage:
SET block_encryption_mode = 'aes-256-cbc'
I can not set it as global variable as other users are using the server and may use the default block_encryption_mode.
I know I can use the statement using ASP/PHP on the beginning of each webpage, but that seems like using too much resources; every user will execute the SET statement on every page...
Is there a way to SET variable or execute some other SQL statement at the beggining on each session, like an onstart event like ASP has, maybe? Or how could I achieve my goal without executing the query for each user on every page I have?
You can use the init_connect variable.
A string to be executed by the server for each client that connects. The string consists of one or more SQL statements, separated by semicolon characters.
You can also distinguish the users with code like this:
IF (CURRENT_USER() = 'special_crypto_dude#localhost') THEN
SET SESSION block_encryption_mode = 'aes-256-cbc';
END IF;
It is safe to call SET on every page as it executes in orders of microseconds. There is literally no overhead calling SET on already open connection.
Unless you can apply this setting globally, I would not bother. Just set the block_encryption_mode (together with collation and timezone) directly after acquiring the database connection handle.
The MySQL manual on user variables says that
As a general rule, other than in SET statements, you should never assign a value to a user variable and read the value within the same statement. For example, to increment a variable, this is okay:
SET #a = #a + 1;
For other statements, such as SELECT, you might get the results you expect, but this is not guaranteed. In the following statement, you might think that MySQL will evaluate #a first and then do an assignment second:
SELECT #a, #a:=#a+1, ...;
However, the order of evaluation for expressions involving user variables is undefined.
This is apparently comparing apples and oranges. SELECT #a:=#a+1; would be the equivalent, and would be just as fine as SET #a=#a+1, since #a+1 has always to be evaluated before assigning its value to #a.
However, if we do the same for SET as for SELECT, ie.
SET #b=#a,#a=#a+1;
is the value of #b guaranteed to contain the value of #a from before executing the statement? Or can it contain the incremented value?
The following questions can be asked:
Will the expressions be evaluated from left to right? Ie. after
SET #a =(#v:='x'), #b = (#v:='y');
is #v guaranteed to be 'y'?
Will the assignments be done from left to right? Ie., after
SET #v='x',#v='y';
is #v guaranteed to be 'y'?
Will all evaluations happen strictly before all assignments? Ie., after
SET #a='x',#v=#a,#a='y';
is #v guaranteed to contain the value of #a from before the statement is executed? ("If any variable assignment in a SET statement fails, the entire statement fails and no variables are changed" from the manual suggests this, though it would also allow SET to save the old values and restore them when an assignment fails.)
Although the MySQL manual on stored program variables says that 'Variables can be set directly with the SET statement. See Section 13.7.4.1, “SET Syntax for Variable Assignment”.', I noticed that when I do
DELIMITER //
CREATE PROCEDURE TEST_SET()
SQL SECURITY INVOKER
BEGIN
SET #v='BEFORE',#a='BEFORE';
SET #a='x',#v=#a,#a='y',#a=(SELECT * FROM doesntexist);
END//
DELIMITER ;
and then
CALL TEST_SET();
SELECT #a,#v;
apparently the SET did evaluations and assignments strictly in alternation from left to right, until it hit the error. This is different behavior from executing the SET outside of the stored procedure, and no "If any variable assignment in a SET statement fails, ... no variables are changed." I am confused.
The MySQL manual on SET does not provide answers to these questions.
Please note that it does not help try the statements with MySQL and see what result is obtained. I want to know what is guaranteed.
Finding issue in achieving below problem in SSIS.
I have a variable in SSIS #Select which is initialized with a SQL task in SSIS as below.
#Select='Select column1, column2 from tableName', like a dynamic select query, now I want to Execute #Select variable(which should execute select query inside it) to return the full result set in a separate SQL task I have tried it like below but not succeeded.
Declare #Query Varchar(2000)
SET #Query=? // here ? will store the select query in #Select variable
EXEC (#Query) // executing to return result set??
Can anyone help me to achieve this??
If you want to execute a dynamic select query in SSIS then use an Execute SQL Task and edit the task.
Set the ResultSet option to Full Result Set if you are expecting multiple rows and Single Row for only one row. Add your DB connection name to the connection property and ensure that it is in the list of connection managers and configured correctly. You can set the SQLSourceType to Variable and specify the variable you want to use below that. Although using the Direct Input option is just as good where you specify your SQL Statement. Now set the variable you want the ResultSet to write to in the Result Set tab, which is in the left column of the task editor. you can even specify the parameter variable you would like to use in the Parameter Mapping tab.
You can click on Build Query to see if your query works. Hope this helps and let me know if I missed anything :)