Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mysql 'VALUES function' is deprecated

Tags:

python

mysql

This is my python code which prints the sql query.

def generate_insert_statement(column_names, values_format, table_name, items, insert_template=INSERT_TEMPLATE, ):
    return insert_template.format(
        column_names=",".join(column_names),
        values=",".join(
            map(
                lambda x: generate_raw_values(values_format, x),
                items
            )
        ),
        table_name=table_name,
        updates_on=create_updates_on_columns(column_names)
    )
query = generate_insert_statement(table_name=property['table_name'],
        column_names=property['column_names'],
        values_format=property['values_format'], items=batch)
        print(query) #here
        execute_commit(query)

When printing the Mysql query my Django project shows following error in the terminal:

'VALUES function' is deprecated and will be removed in a future release. Please use an alias (INSERT INTO ... VALUES (...) AS alias) and replace VALUES(col) in the ON DUPLICATE KEY UPDATE clause with alias.col instead

Mysql doumentation does not say much about it.What does this mean and how to can i rectify it.

INSERT_TEMPLATE = "INSERT INTO {table_name} ({column_names}) VALUES {values} ON DUPLICATE KEY UPDATE {updates_on};"
like image 657
Pravin Mishra Avatar asked Aug 27 '20 05:08

Pravin Mishra


People also ask

What is values in MySQL?

VALUES is a DML statement introduced in MySQL 8.0. 19 which returns a set of one or more rows as a table. In other words, it is a table value constructor which also functions as a standalone SQL statement.

What is on duplicate key update in MySQL?

ON DUPLICATE KEY UPDATE is a MariaDB/MySQL extension to the INSERT statement that, if it finds a duplicate unique or primary key, will instead perform an UPDATE. The row/s affected value is reported as 1 if a row is inserted, and 2 if a row is updated, unless the API's CLIENT_FOUND_ROWS flag is set.

What is insert ignore in MySQL?

The INSERT IGNORE command keeps the first set of the duplicated records and discards the remaining. The REPLACE command keeps the last set of duplicates and erases out any earlier ones. Another way to enforce uniqueness is to add a UNIQUE index rather than a PRIMARY KEY to a table.


Video Answer


1 Answers

Basically, mysql is looking toward removing a longstanding non-standard use of the values function to clear the way for some future work where the SQL standard allows using a VALUES keyword for something very different, and because how the VALUES function works in subqueries or not in a ON DUPLICATE KEY UPDATE clause can be surprising.

You need to add an alias to the VALUES clause and then use that alias instead of the non-standard VALUES function in the ON DUPLICATE KEY UPDATE clause, e.g. change

INSERT INTO foo (bar, baz) VALUES (1,2)
ON DUPLICATE KEY UPDATE baz=VALUES(baz)

to

INSERT INTO foo (bar, baz) VALUES (1,2) AS new_foo
ON DUPLICATE KEY UPDATE baz=new_foo.baz

(This only works on mysql 8+, not on older versions or in any version of mariadb through at least 10.7.1)

From https://dev.mysql.com/worklog/task/?id=13325:

According to the SQL standard, VALUES is a table value constructor that returns a table. In MySQL this is true for simple INSERT and REPLACE statements, but MySQL also uses VALUES to refer to values in INSERT ... ON DUPLICATE KEY UPDATE statements. E.g.:

INSERT INTO t(a,b) VALUES (1, 2) ON DUPLICATE KEY UPDATE a = VALUES (b) + 1;

VALUES (b) refers to the value for b in the table value constructor for the INSERT, in this case 2.

To make the value available in simple arithmetic expressions, it is part of the parser rule for simple_expr. Unfortunately, this also means that VALUES can be used in this way in a lot of other statements, e.g.:

SELECT a FROM t WHERE a=VALUES(a);

In all such statements, VALUES returns NULL, so the above query would not have the intended effect. The only meaningful usage of VALUES as a function, rather than a table value constructor, is in INSERT ... ON DUPLICATE KEY UPDATE. Also, the non-standard use in INSERT ... ON DUPLICATE KEY UPDATE does not extend to subqueries. E.g.:

INSERT INTO t1 VALUES(1,2) ON DUPLICATE KEY UPDATE a=(SELECT a FROM t2 WHERE b=VALUES(b));

This does not do what the user expects. VALUES(b) will return NULL, even if it is in an INSERT .. ON DUPLICATE KEY UPDATE statement.

The non-standard syntax also makes it harder (impossible?) to implement standard behavior of VALUES as specified in feature F641 "Row and table constructors".

like image 91
ysth Avatar answered Sep 21 '22 15:09

ysth