View and table in same name is it possible - mysql

Is it possible to create a mysql view and table in same name
for example i have a table hs_hr_employee i want create a view as a same name
create VIEW hs_hr_employee AS SELECT * from hs_hr_employee;
I m getting following error
#1050 - Table 'hs_hr_employee' already exists
Any help Thankful
Regards

you can't , give to view different name like
hs_hr_employee_view
from manual
Within a database, base tables and views share the same namespace, so
a base table and a view cannot have the same name.

As stated, you can't do it with views, but you can with temporary tables.
If you create a temporary table with the same name as an actual table, the temporary table will shadow (hide) the actual table. This means that you can't access the actual table until you have dropped the temporary table:
mysql> create table t select 1; # actual table t
Query OK, 1 row affected (0.58 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> create temporary table t select*from t; # temp table t
Query OK, 1 row affected (0.53 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> insert t select 2; # t refers to the temp table
Query OK, 1 row affected (0.06 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> select*from t; # temp table
+---+
| 1 |
+---+
| 1 |
| 2 |
+---+
2 rows in set (0.00 sec)
mysql> drop table t; # temp table
Query OK, 0 rows affected (0.06 sec)
mysql> show tables like "t"; # verify that actual table still exists. show tables will not show temporary tables
+--------------------+
| Tables_in_test (t) |
+--------------------+
| t |
+--------------------+
1 row in set (0.00 sec)
mysql>
mysql> select*from t; # now t refers to the actual table
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)
mysql> drop table t; # actual table
Query OK, 0 rows affected (0.14 sec)
mysql>
However, temporary tables are gone (even if you do not drop them) once your session is disconnected. You'll need to re-create them every time you connect.

Yes, if you create it under a different schema.
for example
dbo.Customers
user.customers (this could be a view)
You can call it by including the schema or if you call it from a user that is assigned the schema.
This is for MS SQL server.

Not only in mysql server but in any sqldialect, tables and views in the same schema can't be with the same name as it will lead to ambiguity when you fire a select query like from where to select the columns either from table or view.

Related

is this a mysql bug about update check?

we have databases db1 and db2, each of them has a table t with a column a
create database db1;
create database db2;
create table t(a int);
insert into t values (1);
then we use db1 and run the SQLs:
mysql> update db2.t, (select 1 as a) as t set db2.t.a=1;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0 Changed: 0 Warnings: 0
mysql> update (select 1 as a) as t, db2.t set db2.t.a=1;
ERROR 1288 (HY000): The target table t of the UPDATE is not updatable
As you can see, the first SQL runs successfully, and the second report an error.
Why does this happen? is this a MySQL bug?
I am using MySQL version:
mysql> select version();
+-------------------------+
| version() |
+-------------------------+
| 8.0.22-0ubuntu0.20.04.3 |
+-------------------------+
1 row in set (0.00 sec)

Can't create table throught a view with function inside mysql

I created two tables
CREATE TABLE `prova` (
`id` int NOT NULL AUTO_INCREMENT ,
`text` varchar(255) NOT NULL ,
PRIMARY KEY (`id`)
)
;
CREATE TABLE `prova2` (
`id2` int NOT NULL AUTO_INCREMENT ,
`text2` varchar(255) NOT NULL ,
PRIMARY KEY (`id2`)
)
;
insert into prova (text) values ('ffffff');
A function does a select on table one and inserts a row in table two only if the value of variable #test is set to 0:
CREATE FUNCTION `get_prova`()
RETURNS int(11)
BEGIN
declare id_prova int ;
declare test int ;
set #test = 1;
set #id_prova = (select id from prova limit 1);
if (#test = 0) THEN
insert into prova2 (text2) values ('dddd');
end if;
return #id_prova;
END;
then, I create a view that calls this function:
create view temp_prova as
select id,
text,
get_prova() as prova
from prova
I want to create table 3 that contains the result of view:
CREATE TABLE zzz_prova SELECT * FROM temp_prova;
but when I try to create table zzz_prova I get this error:
[SQL]CREATE TABLE zzz_prova SELECT * FROM temp_prova; [Err] 1746 -
Can't update table 'prova2' while 'zzz_prova' is being created.
Why does this error show up?
Thank you
What version of MySQL are you running?
Changes in MySQL 5.6.2 (2011-04-11)
Incompatible Change; Replication: It is no longer possible to issue a
CREATE TABLE ... SELECT statement which changes any tables other than
the table being created. Any such statement is not executed and
instead fails with an error.
One consequence of this change is that FOR UPDATE may no longer be
used at all with the SELECT portion of a CREATE TABLE ... SELECT.
This means that, prior to upgrading from a previous release, you
should rewrite any CREATE TABLE ... SELECT statements that cause
changes in other tables so that the statements no longer do so.
This change also has implications for statement-based replication
between a MySQL 5.6 (or later slave) and a master running a previous
version of MySQL. In such a case, if a CREATE TABLE ... SELECT
statement on the master that causes changes in other tables succeeds
on the master, the statement nonetheless fails on the slave, causing
replication to stop. To keep this from happening, you should either
use row-based replication, or rewrite the offending statement before
running it on the master. (Bug #11749792, Bug #11745361, Bug #39804,
Bug #55876)
References: See also Bug #47899.
UPDATE
MySQL 5.5:
mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.5.47 |
+-----------+
1 row in set (0.00 sec)
mysql> DROP FUNCTION IF EXISTS `f`;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TABLE IF EXISTS `t1`;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TABLE IF EXISTS `t2`;
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER |
mysql> CREATE FUNCTION `f`()
-> RETURNS INT
-> BEGIN
-> INSERT INTO `t2` VALUES (1);
-> RETURN 1;
-> END|
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CREATE TABLE `t2`(`c1` INT);
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `t1` SELECT `f`() `c1`;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SELECT `c1` FROM `t1`;
+------+
| c1 |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql> SELECT `c1` FROM `t2`;
+------+
| c1 |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
MySQL 5.6:
mysql> SELECT VERSION();
+-----------------+
| VERSION() |
+-----------------+
| 5.6.25 |
+-----------------+
1 row in set (0.00 sec)
mysql> DROP FUNCTION IF EXISTS `f`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DROP TABLE IF EXISTS `t1`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DROP TABLE IF EXISTS `t2`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DELIMITER |
mysql> CREATE FUNCTION `f`()
-> RETURNS INT
-> BEGIN
-> INSERT INTO `t2` VALUES (1);
-> RETURN 1;
-> END|
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CREATE TABLE `t2`(`c1` INT);
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `t1` SELECT `f`() `c1`;
ERROR 1746 (HY000): Can't update table 't2' while 't1' is being created.

MySQL Stored procedure remembers outdated temporary table schema, leading to unknown column error

In the following MySQL code, the first two blocks drop and create a temporary table _temp (with different column labels) and select * from it without a problem. Then, I create a stored procedure that does the same thing (i.e., select * from _temp), and it works first time, but not the second, failing with
ERROR 1054 (42S22): Unknown column 'test._temp.f' in 'field list'
It seems like select * from _temp on its own correctly handles the change in table columns, but the previous columns names are remembered across stored procedure calls. Am I doing something wrong, or is there a workaround?
MySQL Code
drop temporary table if exists _temp;
create temporary table _temp select 'first' as f;
select * from _temp;
drop temporary table if exists _temp;
create temporary table _temp select 'second' as s;
select * from _temp;
drop procedure if exists selectTemp;
create procedure selectTemp()
select * from _temp;
drop temporary table if exists _temp;
create temporary table _temp select 'first' as f;
call selectTemp();
drop temporary table if exists _temp;
create temporary table _temp select 'second' as s;
call selectTemp();
Transcript
$ mysql --version
mysql Ver 14.14 Distrib 5.5.38, for debian-linux-gnu (x86_64) using readline 6.2
mysql> source temp.sql
Query OK, 0 rows affected (0.01 sec)
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
+-------+
| f |
+-------+
| first |
+-------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
+--------+
| s |
+--------+
| second |
+--------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
+-------+
| f |
+-------+
| first |
+-------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
ERROR 1054 (42S22): Unknown column 'test._temp.f' in 'field list'
After paring this down to a minimal working example, and distilling the essential elements, searching for a bug report, this became much easier. It turns out that this was reported all the way back in 2005 as:
Bug #12257 SELECT * inside PROCEDURE gives "Unknown column" on second loop if tbl changed
Some of the bugs marked as a duplicate of that are actually more along the lines of the example:
Bug #15766 select * from table inside stored procedure uses old field names
Bug #49333 Unknown column 'test.TEMPTABLE.column1' in 'field list'
Bug #62406 new cursor, on table with same name but different structure as used before fails
The bug is closed, but apparently not fixed yet, though 5.6 mentions the behavior. From the comments in the bug report:
Noted in 5.6.6 changelog.
"Unknown column" errors or bad data could result from changing the set
of columns in a table used within a stored program between executions
of the program or while the table was used within a program loop.

MySQL SELECT * fails on temporary table created by PREPARE using dynamic column and table names after first pass

MySQL 5.2, CentOS 6.4.
MySQL SELECT * fails on temporary table created by PREPARE using dynamic column and table names after first pass, when column name and table name are changed to different values from the first pass.
The work-around is to use a column alias that remains the same from pass to pass.
DROP PROCEDURE IF EXISTS test1;
DELIMITER $$
CREATE PROCEDURE test1( column_name VARCHAR(20), table_name VARCHAR(20) )
BEGIN
SET #prepared_stmt_arg = 'prepared_stmt_arg_value';
DROP TABLE IF EXISTS tmp1;
CREATE TEMPORARY TABLE tmp1
SELECT 1 AS col_tmp1;
DROP TABLE IF EXISTS tmp2;
CREATE TEMPORARY TABLE tmp2
SELECT 2 AS col_tmp2;
# drop tmp table if it exists
DROP TABLE IF EXISTS tmp_test1;
# prepared statement
SET #prepared_stmt =
CONCAT("
CREATE TEMPORARY TABLE tmp_test1
SELECT ? AS prepared_stmt_arg, ", column_name, " # AS constant_col_alias
FROM ", table_name, "
"); # END statement
# display prepared statement before executing it
SELECT #prepared_stmt;
# prepare the statement
PREPARE ps FROM #prepared_stmt;
# execute
EXECUTE ps USING #prepared_stmt_arg;
# deallocate
DEALLOCATE PREPARE ps;
# display
SELECT * FROM tmp_test1;
END $$
DELIMITER ;
The SELECT statement at the very end of the procedure fails. (You may need to scroll down to see the error message.)
mysql> CALL test1('col_tmp1', 'tmp1');
+---------------------------------------------------------------------------------------------------------------------------------+
| #prepared_stmt |
+---------------------------------------------------------------------------------------------------------------------------------+
|
CREATE TEMPORARY TABLE tmp_test1
SELECT ? AS prepared_stmt_arg, col_tmp1 # AS constant_col_alias
FROM tmp1
|
+---------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
+-------------------------+----------+
| prepared_stmt_arg | col_tmp1 |
+-------------------------+----------+
| prepared_stmt_arg_value | 1 |
+-------------------------+----------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> CALL test1('col_tmp2', 'tmp2');
+---------------------------------------------------------------------------------------------------------------------------------+
| #prepared_stmt |
+---------------------------------------------------------------------------------------------------------------------------------+
|
CREATE TEMPORARY TABLE tmp_test1
SELECT ? AS prepared_stmt_arg, col_tmp2 # AS constant_col_alias
FROM tmp2
|
+---------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
ERROR 1054 (42S22): Unknown column 'dev.tmp_test1.col_tmp1' in 'field list'
However, if you uncomment the column alias (remove the # just before AS constant_col_alias), all works well. (You may need to scroll down to see Query OK.)
mysql> CALL test1('col_tmp1', 'tmp1');
+-------------------------------------------------------------------------------------------------------------------------------+
| #prepared_stmt |
+-------------------------------------------------------------------------------------------------------------------------------+
|
CREATE TEMPORARY TABLE tmp_test1
SELECT ? AS prepared_stmt_arg, col_tmp1 AS constant_col_alias
FROM tmp1
|
+-------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
+-------------------------+--------------------+
| prepared_stmt_arg | constant_col_alias |
+-------------------------+--------------------+
| prepared_stmt_arg_value | 1 |
+-------------------------+--------------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> CALL test1('col_tmp2', 'tmp2');
+-------------------------------------------------------------------------------------------------------------------------------+
| #prepared_stmt |
+-------------------------------------------------------------------------------------------------------------------------------+
|
CREATE TEMPORARY TABLE tmp_test1
SELECT ? AS prepared_stmt_arg, col_tmp2 AS constant_col_alias
FROM tmp2
|
+-------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
+-------------------------+--------------------+
| prepared_stmt_arg | constant_col_alias |
+-------------------------+--------------------+
| prepared_stmt_arg_value | 2 |
+-------------------------+--------------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Well it seems to be a bug or a feature (if you want) up to version 5.6.
See Bug #32868 Stored routines do not detect changes in meta-data.
Workaround: flush the stored routine cache by doing this:
CREATE OR REPLACE VIEW tmpview AS SELECT 1;
Here is SQLFiddle demo MySql 5.1.X
Here is SQLFiddle demo MySql 5.5.X
If you comment out CREATE OR REPLACE VIEWtmpviewAS SELECT 1 you'll get your error.
Here is SQLFiddle demo MySql 5.6.X shows that it's no longer a problem
Now you have at least these options to go with:
don't use SELECT * use explicit column names instead.
use proposed workaround
upgrade to 5.6.X

2 servers, 2 memory tables, different sizes

I have got two servers both running a MySQL instance. The first one, server1, is running MySQL 5.0.22. The other one, server2, is running MySQL 5.1.58.
When I create a memory table on server1 and I add a row its size is instantly 8,190.0 KiB.
When I create a memory table on server2 and I add a row its size is still only some bytes, though.
Is this caused by the difference in MySQL version or (hopefully) is this due to some setting I can change?
EDIT:
I haven't found the reason for this behaviour yet, but I did found a workaround. So, for future references, this is what fixed it for me:
All my memory tables are made once and are read-only from thereon. When you specify to MySQL the maximum number of rows your table will have, its size will shrink. The following query will do that for you.
ALTER TABLE table_name MAX_ROWS = N
Factor of 2?
OK, the problem likely is caused by the UTF-8 vs latin1
:- http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html
You can check the database connection, database default character set for both servers.
here is the testing I have just done :-
mysql> create table test ( name varchar(10) ) engine
-> =memory;
Query OK, 0 rows affected (0.03 sec)
mysql> show create table test;
+-------+------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------------------+
| test | CREATE TABLE `test` (
`name` varchar(10) DEFAULT NULL
) ENGINE=MEMORY DEFAULT CHARSET=latin1 |
+-------+------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> insert into test values ( 1 );
mysql> set names utf8;
Query OK, 0 rows affected (0.01 sec)
mysql> create table test2 ( name varchar(10) ) engine =memory default charset = utf8;
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
mysql> insert into test2 values ( convert(1 using utf8) );
Query OK, 1 row affected (0.01 sec)
mysql> select table_name, avg_row_length from information_schema.tables where TABLE_NAME in( 'test2', 'test');
+------------+----------------+
| table_name | avg_row_length |
+------------+----------------+
| test | 12 |
| test2 | 32 |
+------------+----------------+
2 rows in set (0.01 sec)