Mysql Error 1356 - Views - mysql

When i'll try create some but when i call it appears the error 1356:
Creating the View
CREATE VIEW monitoring_consult AS (
SELECT
m.id,
account.valor AS 'phone_number',
IF((c.valor REGEXP '^[0-9]+$' OR c.valor IS NULL) AND cn.short_name IS NOT NULL, cn.short_name, c.valor) AS 'category',
IF(pn.id IS NOT NULL, pn.id, p.valor) AS 'provider',
n.valor AS 'nominal',
m.last_page,
pn.name AS 'provider_name',
IF(pay.valor is null, 'Uncompleted', pay.valor) AS 'payment',
timeEnd,
DATE_FORMAT(m.timeEnd, '%d/%m/%Y') as 'date'
FROM
monitoring AS m
LEFT JOIN feature AS account ON m.id = account.id AND account.valor IS NOT NULL AND (account.page = 'PV') AND account.type = 'send'
LEFT JOIN feature AS c ON m.id = c.id_monitoring AND c.valor IS NOT NULL AND (c.page = 'MA' OR c.page = 'IN') AND c.type = 'select'
LEFT JOIN feature AS p ON m.id = p.id_monitoring AND p.page = 'PO' AND p.valor IS NOT NULL AND p.type = 'select'
LEFT JOIN feature AS n ON m.id = n.id_monitoring AND n.valor IS NOT NULL AND n.page = 'OAP' AND n.type = 'select'
LEFT JOIN feature AS pay ON m.id = pay.id_monitoring AND m.last_page = 'OK' AND pay.type = 'userAction' AND pay.name = 'paymentStatus' AND pay.valor = 'Completed'
LEFT JOIN terminais AS term ON m.id_terminal = term.id
LEFT JOIN provider AS pn ON (p.valor = pn.id) OR (c.valor REGEXP '^[0-9]+$' AND c.valor = pn.id)
LEFT JOIN category AS cn ON pn.id_category = cn.id
group by m.id
having category is not null
)
Calling the view:
select * from monitoring_consult
Return:
Error Code: 1356. View 'qiwi.monitoring_consult' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
Mysql Version - 5.5.32-log
Do someone know why this happened?

this particular problem happen to me every time i imported a mysqldump export, with automatic views creation inside it,
such problem came out because of the creation of the view in the mysqldump (when you reimport again), with "SQL SECURITY DEFINER",
i don't known if it is a mysql bug, but for me deleting and applying new permission to the view, does not solve the problem, recreating the view without the "SQL SECURITY DEFINER", solve my problem, i hope this is your case.
Ciao.

These are the cases
MySQL loggined user has not the privilege view the monitoring_consult view
Any of your joined table not exist
Any of your field that you are trying fetch not exist ( You might be deleted )

I was getting the same error code and was able to pin it down somewhat. It appears to arise when an object two (or more?) levels down is no longer available. Here is some code to recreate the issue.
create table `table1` (`id` int(11), `col1` varchar(16);
insert into `table1` (`id`, `col1`) values (1, 'Foo'), (2, 'Bar');
create view `view_sub` as SELECT `id`, `col1` from `table1`;
# if you drop here you'll get error code 1146: table1 doesn't exist
create view `view_err` as SELECT `id`, `col1` from `view_sub`;
drop table `table1`;
select * from `view_err`
# should get you error code 1356: references invalid table(s), etc
I don't know if anything in your from clause is a view, but the (what appears to be) typo of terminais may be causing it.

When creating the view, try to specify a definer like this:
CREATE
ALGORITHM = UNDEFINED
DEFINER = `user`#`%`
SQL SECURITY DEFINER
VIEW `monitoring_consult` AS ...
where the DEFINER usermust have the appropriate rights to any table that is linked to the view

Hi I got this error after changing my database model. Happened that an existing view referenced non existing fields.
So the solution was delete the current view and create a new one, considering the new model instead of focusing on user privileges.
Hope it helps to someone :)

I had the same problem. While I still don't know what it caused the problem, because none of the tables the view uses had been changed.
My solution was to drop the old view and create a new one this time I specified at the top of my view the following.
use databasename;

This message can sometimes be misleading. I was getting the same warning even though i had made sure that the definer user had the correct permissions and all the referenced tables/fields were OK.
After running
show create view viewName;
I noticed that the output contained 1 warning so after that I run
show warnings;
And that showed me the actual problem.

Related

Editing the Results of a MySQL View

I'm trying to create a view in my relational MySQL database that will allow the user to update football match results from one (virtual) table within phpMyAdmin.
I have the view all setup visually how I want, and I am able to edit most of the fields, except I am getting error messages. If, for instance, I update the number of goals scored for a team, I get the following error messages shown below. It will still update that record, however, because if I refresh the page, that particular entry will change to what I entered.
I am aware that you cannot have a primary key on a view, but in terms of indexing, shouldn't the existing relationships be sufficient for this to work?
Another issue is updating the referee field. As this is a concatenated field (first_name + last_name), I cannot attempt to update it from the view.
This is my database structure:
This is the code for my view:
CREATE VIEW `view1_match_main` AS
SELECT
`match_main`.`match_id` AS `Match ID`,
`season`.`season` AS `Season`,
`match_status`.`status_no` AS `Status`,
`match_main`.`date_time` AS `Date`,
`c1`.`club_name` AS `Home Club`,
`mr1`.`goal` AS `Home Goals`,
`mr2`.`goal` AS `Away Goals`,
`c2`.`club_name` AS `Away Club`,
CONCAT(`referee`.`referee_first_name`,
' ',
`referee`.`referee_last_name`) AS `Referee`,
`stadium`.`stadium_name` AS `Stadium`,
`match_main`.`attendance` AS `Attendance`,
`match_main`.`bbc_url` AS `BBC URL`,
`match_main`.`sky_url` AS `Sky URL`
FROM
((((((((`match_main`
LEFT JOIN `referee` ON ((`match_main`.`referee_id` = `referee`.`referee_id`)))
LEFT JOIN `season` ON ((`match_main`.`season_id` = `season`.`season_id`)))
LEFT JOIN `match_status` ON ((`match_main`.`status_id` = `match_status`.`status_id`)))
LEFT JOIN `match_result` `mr1` ON (((`mr1`.`match_id` = `match_main`.`match_id`)
AND (`mr1`.`home_team` = 1))))
LEFT JOIN `club` `c1` ON ((`c1`.`club_id` = `mr1`.`club_id`)))
LEFT JOIN `match_result` `mr2` ON (((`mr2`.`match_id` = `match_main`.`match_id`)
AND (`mr2`.`home_team` = 0))))
LEFT JOIN `club` `c2` ON ((`c2`.`club_id` = `mr2`.`club_id`)))
LEFT JOIN `stadium` ON ((`c1`.`stadium_id` = `stadium`.`stadium_id`)))
ORDER BY `season`.`season` DESC , `match_main`.`date_time` , `c1`.`club_name`

MySQL Error 1146: Table 'sys.campaign_view' doesn't exist and MySQL Error 1356

I've created a view called campaign_view. The view is comprised of info spread across numerous tables (I use six joins). When I try to add a seventh join, I get 'Error 1146: Table sys.campaign_view doesn't exist'.
I have tried restarting my server as suggested with no luck.
I have tried actually removing the view and recreating it. I cannot recreate with the seventh join instruction without experiencing Error 1356.
I've tried using the reserved word FORCE to get around 1356, but that doesn't resolve the issue either. I'm almost certain it's something easy that I'm missing.
Ultimately what I'm trying to accomplish is to add three new columns to the campaign_view view from another account_stat_summaries view. There are six rows in campaign_view and three rows in account_stat_summaries. I want them paired based on the account_key which exists in both tables, and I would like to end up with a table that contains six rows; this should be a left join with the campaign_view being the left view/table.
One suggestion was that my left join is listed before the other joins (all inner joins be default), but that didn't fix it either. Explicitly listing every join also didn't resolve the issue.
I've posted my code below which successfully created my table and the addition join that breaks everything.
Original Query (Successfully creates table)
CREATE
VIEW `campaign_view` AS
SELECT
`camp`.`campaign_key` AS `ad_id`,
`a`.`modified` AS `modified`,
`a`.`fname` AS `fname`,
`a`.`lname` AS `lname`,
`a`.`account_key` AS `account_table_key`,
`s`.`status` AS `account_status`,
`a`.`account_comment` AS `account_comment`,
`a`.`platform` AS `platform`,
`a`.`details` AS `details`,
`a`.`account_claimed` AS `account_claimed`,
`a`.`pixel` AS `pixel`,
`a`.`angle` AS `angle`,
`c`.`headline` AS `headline`,
`c`.`body` AS `body`,
`c`.`link_to_graphic` AS `link_to_graphic`,
`su`.`url` AS `url`,
`su`.`site_claimed` AS `site_claimed`,
`camp`.`media_buyer` AS `media_buyer`,
`camp`.`uploader` AS `uploader`,
`a`.`created` AS `date_created`,
`v`.`name` AS `vertical`,
`camp`.`campaign_name` AS `campaign_name`,
`ads`.`adset_key` AS `adset_key`,
`ads`.`country` AS `country`
FROM
((((((`accounts` `a`
JOIN `campaigns` `camp` ON ((`camp`.`account_key` = `a`.`account_key`)))
JOIN `adsets` `ads` ON ((`ads`.`campaign_key` = `camp`.`campaign_key`)))
JOIN `content` `c` ON ((`c`.`adset_key` = `ads`.`adset_key`)))
JOIN `status` `s` ON ((`a`.`status_key` = `s`.`status_key`)))
JOIN `safe_urls` `su` ON ((`su`.`safe_url_key` = `a`.`safe_url_key`)))
JOIN `verticals` `v` ON ((`v`.`vertical_key` = `a`.`vertical_key`)))
Addition That Breaks Everything
JOIN `account_stat_summaries` `ass` ON ((`a`.`account_key` = `ass`.`account_key`)))
I would be so grateful if someone could assist!

Record does not appear in view yet appears in result of query for view

In MySQL, I have defined a view on two tables as follows:
delimiter $$
CREATE ALGORITHM=UNDEFINED DEFINER=`root`#`localhost`<br/>
SQL SECURITY DEFINER VIEW `test`.`viewinschrijvingen` AS<br/>
select `i`.`student` AS `student`,<br/>
`i`.`opleidingscode` AS `opleidingscode`,<br/>
`i`.`inschrijvingsvorm` AS `inschrijvingsvorm`,<br/>
`i`.`brin` AS `brin`,<br/>
`i`.`brinvolgnummer` AS `brinvolgnummer`,<br/>
`o`.`onderwijsvorm` AS `onderwijsvorm`,<br/>
`o`.`opleidingniveau` AS `opleidingniveau`,<br/>
`o`.`naamopleidingkort` AS `naamopleidingkort`,<br/>
`o`.`instelling` AS `instelling`,<br/>
`o`.`studielast` AS `studielast`,<br/>
date_format(max(str_to_date(`i`.`datuminschrijving`,'%Y-%m-%d')),'%Y-%m-%d') AS `datuminschrijving`,<br/>
`o`.`gemeentenaam` AS `gemeentenaam` from<br/>
(`test`.`inschrijvingen` `i` left outer join `test`.`opleidingen` `o`<br/>
on((`i`.`opleidingscode` = `o`.`opleidingscode`)))<br/>
group by `i`.`opleidingscode`,`i`.`brin`,`i`.`brinvolgnummer`$$<br/>
When I query this view for the information on a specific student:
SELECT * FROM test.viewinschrijvingen WHERE student = '310018717'
the result is empty (no records returned). When I browse through the records in the view, there is no record for student 310018717 (obviously).
However, when I execute the query I used to create the view directly:
select `i`.`student` AS `student`,<br/>
`i`.`opleidingscode` AS `opleidingscode`,<br/>
`i`.`inschrijvingsvorm` AS `inschrijvingsvorm`,<br/>
`i`.`brin` AS `brin`,<br/>
`i`.`brinvolgnummer` AS `brinvolgnummer`,<br/>
`o`.`onderwijsvorm` AS `onderwijsvorm`,<br/>
`o`.`opleidingniveau` AS `opleidingniveau`,<br/>
`o`.`naamopleidingkort` AS `naamopleidingkort`,<br/>
`o`.`instelling` AS `instelling`,<br/>
`o`.`studielast` AS `studielast`,<br/>
date_format(max(str_to_date(`i`.`datuminschrijving`,'%Y-%m-%d')),'%Y-%m-%d') AS `datuminschrijving`,<br/>
`o`.`gemeentenaam` AS `gemeentenaam` from<br/>
(`test`.`inschrijvingen` `i` left outer join `test`.`opleidingen` `o`
on((`i`.`opleidingscode` = `o`.`opleidingscode`)))<br/>
WHERE student = '310018717'<br/>
group by `i`.`opleidingscode`,`i`.`brin`,`i`.`brinvolgnummer`<br/>
I do get a result (1 record, which is the result I expected). Can anybody help me to find what is causing this behaviour?
It probably has to do with your use of MySQL's GROUP BY extension versus the ANSI GROUP BY format. MySQL does not require you to group on every column that is not an aggregate function. For columns that you are not GROUPing on, MySQL can choose whatever value it wants for the column. In your case, you are not using the student field to group and thus it may not be choosing the value you are searching for.
You may want to try this query which uses the ANSI GROUP BY and see if you get the results you want.
delimiter $$
CREATE ALGORITHM=UNDEFINED DEFINER=`root`#`localhost`
SQL SECURITY DEFINER VIEW `test`.`viewinschrijvingen` AS
select
`i`.`student` AS `student`,
`i`.`opleidingscode` AS `opleidingscode`,
`i`.`inschrijvingsvorm` AS `inschrijvingsvorm`,
`i`.`brin` AS `brin`,
`i`.`brinvolgnummer` AS `brinvolgnummer`,
`o`.`onderwijsvorm` AS `onderwijsvorm`,
`o`.`opleidingniveau` AS `opleidingniveau`,
`o`.`naamopleidingkort` AS `naamopleidingkort`,
`o`.`instelling` AS `instelling`,
`o`.`studielast` AS `studielast`,
date_format(max(str_to_date(`i`.`datuminschrijving`,'%Y-%m-%d')),'%Y-%m-%d') AS `datuminschrijving`,
`o`.`gemeentenaam` AS `gemeentenaam`
from `test`.`inschrijvingen` `i`
left outer join `test`.`opleidingen` `o`
on `i`.`opleidingscode` = `o`.`opleidingscode`
group by
`i`.`student`,
`i`.`opleidingscode`,
`i`.`inschrijvingsvorm`,
`i`.`brin` AS `brin`,
`i`.`brinvolgnummer`,
`o`.`onderwijsvorm`,
`o`.`opleidingniveau`,
`o`.`naamopleidingkort`,
`o`.`instelling`,
`o`.`studielast`,
`o`.`gemeentenaam`$$

Updateable mysql views

can i have a advise on how to update a views? this is my created views.. but because of stored functions its not updateable right? do the join query did it not updateable too? and the if function? please help me..sorry for my english.
CREATE
ALGORITHM = UNDEFINED
DEFINER = `root`#`localhost`
SQL SECURITY DEFINER
VIEW `view_attendance_dgv` AS
select
`tbl_stockholders`.`user_id` AS `user_id`,
`tbl_images`.`image_template` AS `Image Template`,
finger_name(`tbl_fingerprints`.`finger`) AS `Enrolled Finger`,
`tbl_users`.`last_name` AS `Last Name`,
`tbl_users`.`first_name` AS `First Name`,
`tbl_users`.`middle_name` AS `Middle Name`,
if((`tbl_stockholders`.`attendance_status` = 0),
'Absent',
'Present') AS `Attendance Status`,
if((`tbl_stockholders`.`voting_status` = 0),
'Not Voted',
'Voted') AS `Voting Status`
from
((((`tbl_stockholders`
join `tbl_shares` ON ((`tbl_stockholders`.`user_id` = `tbl_shares`.`user_id`)))
join `tbl_users` ON ((`tbl_stockholders`.`user_id` = `tbl_users`.`user_id`)))
join `tbl_images` ON ((`tbl_stockholders`.`user_id` = `tbl_images`.`user_id`)))
join `tbl_fingerprints` ON ((`tbl_stockholders`.`user_id` = `tbl_fingerprints`.`user_id`)))
order by `tbl_stockholders`.`user_id`
http://dev.mysql.com/doc/refman/5.6/en/create-view.html
For a view to be updatable, there must be a one-to-one relationship between the rows in the view and the rows in the underlying table. There are also certain other constructs that make a view nonupdatable.
More details are here:
http://dev.mysql.com/doc/refman/5.6/en/view-updatability.html
Yes, I believe in your query, your use of JOINs and functions makes your view non-updatable.

Sql Result IN a Query

dont blame for the database design.I am not its database architect. I am the one who has to use it in current situation
I hope this will be understandable.
I have 3 tables containing following data with no foreign key relationship b/w them:
groups
groupId groupName
1 Admin
2 Editor
3 Subscriber
preveleges
groupId roles
1 1,2
2 2,3
3 1
roles
roleId roleTitle
1 add
2 edit
Query:
SELECT roles
from groups
LEFT JOIN preveleges ON (groups.groupId=preveleges.groupId)
returns specific result i.e roles.
Problem: I wanted to show roleTitle instead of roles in the above query.
I am confused how to relate table roles with this query and returns required result
I know it is feasible with coding but i want in SQL.Any suggestion will be appreciated.
SELECT g.groupName,
GROUP_CONCAT(r.roleTitle
ORDER BY FIND_IN_SET(r.roleId, p.roles))
AS RoleTitles
FROM groups AS g
LEFT JOIN preveleges AS p
ON g.groupId = p.groupId
LEFT JOIN roles AS r
ON FIND_IN_SET(r.roleId, p.roles)
GROUP BY g.groupName ;
Tested at: SQL-FIDDLE
I would change the data structure it self. Since It's not normalised, there are multiple elements in a single column.
But it is possible with SQL, if for some (valid) reason you can't change the DB.
A simple "static" solution:
SELECT REPLACE(REPLACE(roles, '1', 'add'), '2', 'edit') from groups
LEFT JOIN preveleges ON(groups.groupId=preveleges.groupId)
A more complex but still ugly solution:
CREATE FUNCTION ReplaceRoleIDWithName (#StringIds VARCHAR(50))
RETURNS VARCHAR(50)
AS
BEGIN
DECLARE #RoleNames VARCHAR(50)
SET #RoleNames = #StringIds
SELECT #RoleNames = REPLACE(#RoleNames, CAST(RoleId AS VARCHAR(50)), roleTitle)
FROM roles
RETURN #RoleNames
END
And then use the function in the query
SELECT ReplaceRoleIDWithName(roles) from groups
LEFT JOIN preveleges ON(groups.groupId=preveleges.groupId)
It is possible without function, but this is more readable. Made without editor so it's not tested in anyway.
You also tagged the question with PostgreSQL and it's actually quite easy with Postgres to work around this broken design:
SELECT grp.groupname, r.roletitle
FROM groups grp
join (
select groupid, cast(regexp_split_to_table(roles, ',') as integer) as role_id
from privileges
) as privs on privs.groupid = grp.groupid
join roles r on r.roleid = privs.role_id;
SQLFiddle: http://sqlfiddle.com/#!12/5e87b/1
(Note that I changed the incorrectly spelled name preveleges to the correct spelling privileges)
But you should really, really re-design your data model!
Fixing your design also enables you to define foreign key constraints and validate the input. In your current model, the application would probably break (just as my query would), if someone inserted the value 'one,two,three' into the roles table.
Edit
To complete the picture, using Postgres's array handling the above could be slightly simplified using a similar approach as MySQL's find_in_set()
select grp.groupname, r.roletitle
from groups grp
join privileges privs on grp.groupid = privs.groupid
join roles r on r.roleid::text = any (string_to_array(privs.roles, ','))
In both cases if all role titles should be shown as a comma separated list, the string_agg() function could be used (which is equivalent to MySQL's group_concat()
select grp.groupname, string_agg(r.roletitle, ',')
from groups grp
join privileges privs on grp.groupid = privs.groupid
join roles r on r.roleid::text = any (string_to_array(privs.roles, ','))
group by grp.groupname