SET a variable in mysql only once - mysql

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.

Related

Set variable in mysql sql:query

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?

Cannot set a global variable on MySQL

I'm using MySQL in localhost (in ubuntu and also in windows). I want to set a global variable, and I have tried in all ways but even though I get an "ok" message from mysql, then when I do the "select #var" it allways says "NULL".
I've tried:
set global var=17;
set #global.var=17;
set ##var=17;
Can anyone help me?
Thanks in advance.
ps: I have the SUPER privilege.
The variable name var does not reference a valid system variable. The GLOBAL and SESSION keywords in the SET statement are used for specifying the scope when setting MySQL system variables, not MySQL user variables.
Try for example:
SELECT ##global.net_read_timeout ;
SET GLOBAL net_read_timeout = 45 ;
SELECT ##global.net_read_timeout ;
http://dev.mysql.com/doc/refman/8.0/en/set-statement.html
http://dev.mysql.com/doc/refman/5.5/en/set-statement.html
According to the MySQL 5.0 Reference Manual:
User-defined variables are session-specific. That is, a user variable
defined by one client cannot be seen or used by other clients. All
variables for a given client session are automatically freed when that
client exits.
You could consider using an extension like MySQL Global User Variables UDF (old archived link) to use global (persistent shared) variables.
On MySQL, you cannot create custom global or session system variables but can change existed global or session system variables as shown below:
SET GLOBAL max_connections = 1000; -- Existed global system variable
SET SESSION sql_mode = 'TRADITIONAL'; -- Existed session system variable
And, you can create user-defined(custom) variables which are removed when you exit(log out) a session as shown below. User-defined variables exist only in the current session so they cannot be seen by other sessions unless you use performance_schema.user_variables_by_thread:
SET #first_name = 'John', #last_name = 'Smith';

super priviliege not set for master user in aws rds mysql

I have created an AWS RDS instance, I have created my master user with master password, and it is working/connecting fine.
But when I am going to create a function on that instance, it shows me the following error:
ERROR 1418: This function has none of DETERMINISTIC, NO SQL,
or READS SQL DATA in its declaration and binary logging is enabled
(you might want to use the less safe log_bin_trust_function_creator variable).
In my instance the variable log_bin_trust_function_creators shows OFF, and if I try to change the variable using SET GLOBAL log_bin_trust_function_creators = 1;, it gives me another error "Error Code: 1227. Access denied; you need (at least one of) the SUPER privilege(s) for this operation"
Set log_bin_trust_function_creators = 1 for Parameter group of the RDS instance.
Note: Default Parameter-Group is not editable. Create a new Parameter-Group and assign it to the RDS instance by modifying it from UI (AWS Admin Console) OR maybe using commands
DELIMITER $$
CREATE DEFINER=`DB_USERNAME_HERE`#`%` FUNCTION `GetDistance`(coordinate1 VARCHAR(120), coordinate2 VARCHAR(120)) RETURNS decimal(12,8)
READS SQL DATA
BEGIN
DECLARE distance DECIMAL(12,8);
/*Business logic goes here for the function*/
RETURN distance;
END $$
DELIMITER ;
Here, you have to replace DB_USERNAME_HERE with you RDS database username and function names according to you need.
Important thing is: DEFINER=`DB_USERNAME_HERE`#`%`
This was the problem I was facing after setting log_bin_trust_function_creators = 1 in parameter group. And it worked like a charm.
A better way is to apply your own parameter group, with log_bin_trust_function_creators set to true. (its false by default)
This happens when you try to create a procedure/function/view with a DEFINER that is not the current user.
To solve this remove or update the DEFINER clause.

How to use MySQL user-variables with ADO.NET

MySQL SQL commands can contain user variables that start with '#'.
The MySQL ADO.NET connector also uses '#' for command parameters.
Is there a way to escape the '#' character so I can use a user-variable in an SQL statement sent to MySQL via ADO.NET?
I'm trying to do something like this:
UPDATE company
SET next_job_id = #jobid:=next_job_id+1
WHERE company_id = #companyid;
SELECT #jobid;
Where #jobid is a MySQL user variable and #companyid is a parameter.
It's a connection string option - "Allow User Variables=true"
When set to true, parameters are prefixed with '?'.
Update: I've written up more on this, including how to get this to work with ADO.NET and Subsonic. See Here.

Does SQL Server Management Studio (or SQL Server) evaluate *all* expressions?

Here's my configuration:
I have a re-runnable batch script that I use to update my database.
Inside of that batch script, I have code that says the following:
If Table 'A' doesn't exist, then create Table 'A' and insert rows into it.
Later on in that batch script, I create an schemabound indexed view on that table.
And if you didn't already know, indexed views require specific client settings.
Sometimes, when I re-run the script, that is after the table has been created, SQL Server Management Studio evaluates the "insert rows" code, which is protected by the 'If this table doesn't exist' code, and yields the following error:
Msg 1934, Level 16, State 1, Line 15
INSERT failed because the following SET options have incorrect settings: 'CONCAT_NULL_YIELDS_NULL, ANSI_WARNINGS, ANSI_PADDING, ARITHABORT'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.
Please note: If someone were to try this INSERT statement in a vacuum, I would fully expect SSMS to generate this error.
But not when it's protected by a conditional block.
My Question:
Does the SSMS compiler evaluate all expressions, regardless of whether they will actually be executed?
Yes, it evaluates all of them,take a look at this
declare #i int
select #i =1
if #i = 1
begin
declare #i2 int
set #i2 = 5
end
else
begin
declare #i2 int
set #i2 = 5
end
Msg 134, Level 15, State 1, Line 12
The variable name '#i2' has already been declared. Variable names must be unique within a query batch or stored procedure.
Another example with temp tables is here: What is deferred name resolution and why do you need to care?
your only way out would be to wrap it inside dynamic SQL
Note that most of the settings you mention are connection-level, i.e. in case you set/change them they stay in effect unless you close the connection or explicitly change their value.
Returning to your question. The error you mention looks like runtime error, i.e. the INSERT is actually being executed. It would be better if you could show your script (omitting details, but keeping batches).
Edit: it is not SSMS compiler that evaluates SQL you try to execute - it is SQL Server. What do you meant by 'evaluate'? Is it 'execute'? When you run a batch (which is what actually is being executed by a server), SQL Server first does syntactic analysis and throws error in case it finds any syntactic error, nothing is being executed at this point of time. In case syntax is ok, the server starts executing you batch.
Again, the error you show seems to be runtime - so I guess you'd carefully watch for the conditions and track what happens (or provide us more details about 'sometimes').