Updateable mysql views - mysql

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.

Related

MySQL UPDATE with JOINS using MAX

I'm no MySQL guru.
I'm trying to update a table clients.converted from projects.last_update column.
DATETIME: clients.converted (new column as of now).
DATETIME: projects.last_update.
BOOLEAN: projects.converted.
For each client's project, there is the possibility to end the project with a prospect-to-client conversion, if so, (boolean) projects.converted will me TRUE.
What I want is to do an UPDATE statement on clients to fill clients.converted from MAX(projects.last_update) WHERE project's projects.converted = true.
So far I have tried a couple of queries, but this one grasps the idea in a less-confusing way:
UPDATE clients AS `Client`
INNER JOIN projects AS `Project` ON Project.client_id = Client.id
SET Client.converted = MAX(Project.last_update)
WHERE Project.converted = TRUE;
But it's not working (because I can't use MAX function directly on assignment) and I've run out of ideas on how to do an UPDATE with JOINS using the MAX function applied to a DATETIME column.
I did a SELECT statement to gather the information I need first and
it works like a charm:
SELECT Client.id, count(*), MAX(Project.last_update) FROM projects AS `Project`
LEFT JOIN clients AS `Client` ON Client.id = Project.client_id
WHERE Project.converted = TRUE
GROUP BY Client.id;
Any help is very much appreciated!
Thanks in advance.
MAX is an aggregate function, which means it cannot (or rather, generally should not) be used without a GROUP BY; you'll need to use a subquery.
UPDATE clients AS `Client`
INNER JOIN (SELECT client_id, MAX(last_update) AS max_lu
FROM projects
WHERE converted = TRUE
GROUP BY client_id
) AS `Project` ON Project.client_id = Client.id
SET Client.converted = Project.max_lu
;

Using union in codeigniter query builder, and filter in a virtual mysql column

In my project I am using datatables plugin with serverside processing. It works fine untill i do a search or order(sort) operation because it needs active record to do that.
My scenario is, i have an account table, revenue table and payment table, and I want to view all the data of revenue and payment table, thats why I need a union. my query is like below---
SELECT 'Income' as source, fld_type, fld_amount, ta.fld_account as account, fld_date, tbl_revenue.fld_description as fld_traninfo, tbl_revenue.fld_created as created
FROM tbl_revenue JOIN tbl_accounts as ta on tbl_revenue.fld_account_id = ta.fld_id
UNION
SELECT 'Expense' as source, fld_type, fld_amount, tae.fld_account, fld_date, tbl_payment.fld_description as fld_traninfo, tbl_payment.fld_created as created
FROM tbl_payment JOIN tbl_accounts as tae on tbl_payment.fld_account_id = tae.fld_id
Is there any way to use query builder in this query?
And second question, you can see I created a virtual column named 'source', i want to filter this column using where clause with append this query like below
WHERE source like "%a%" limit(10,0)
But this returns that I don't have any column name 'source', how can I filter this column?
Any help is appreciated.
there is a way to do that but its a bit hacky because codeigniter's querybuilder adds an auto SELECT statement to the query if you didn't specify it by yourself
In order to get what you want, you've to split your select statements in 2 queries and add the where clause to this query
Something like that should work:
$strQuery1 = $this->db
->select('income as source, fld_type, fld_amount, ta.fld_account as account, fld_date, tbl_revenue.fld_description as fld_traninfo, tbl_revenue.fld_created as created')
->from('tbl_revenue')
->join('tbl_accounts as ta', 'tbl_revenue.fld_account_id = ta.fld_id')
->get_compiled_select();
$strQuery2 = $this->db
->select('Expense as source, fld_type, fld_amount, ta.fld_account as account, fld_date, tbl_revenue.fld_description as fld_traninfo, tbl_revenue.fld_created as created')
->from('tbl_payment')
->join('tbl_accounts as ta', 'tbl_revenue.fld_account_id = ta.fld_id')
->get_compiled_select();
$strWhere = substr($this->db->like('source', 'a', 'both')->get_compiled_select(), 8);
$query = $this->db->query($strQuery1.' UNION '.$strQuery2.$strWhere);

Join Tables in SQL

I have sql query like this
CREATE ALGORITHM=UNDEFINED DEFINER=`root`#`localhost` SQL SECURITY DEFINER VIEW `IPK` AS select
`ipbmst_fakultas`.`Kode` AS `Fakultas`,
`ipbmst_departemen`.`Kode` AS `Departemen`,
`akdmst_mahasiswamagister`.`NIM` AS `NIM`,
`akdmst_mahasiswamagister`.`TahunMasuk` AS `TahunMasuk`,
`akdhis_kelanjutanstudi`.`IPK` AS `IPK`
from (((((`akdmst_mahasiswamagister` join `akdmst_mayor` on((`akdmst_mahasiswamagister`.`MayorID` = `akdmst_mayor`.`ID`)))
join `ipbmst_departemen` on((`akdmst_mayor`.`DepartemenID` = `ipbmst_departemen`.`ID`)))
join `ipbmst_fakultas` on((`ipbmst_departemen`.`FakultasID` = `ipbmst_fakultas`.`ID`)))
join `ipbmst_orang` on((`akdmst_mahasiswamagister`.`NIM` = `ipbmst_orang`.`NIMS2Key`)))
left join `akdhis_kelanjutanstudi` on((`akdhis_kelanjutanstudi`.`NIM` = `ipbmst_orang`.`NIMS2Key`)));
but, when I tried to open the view, the data couldn't be opened. Maybe it is because of "akdhis_kelanjutanstudi" table that consists of more than 300K data. What should I do to solve this? Thank you in advance
Create InDex On Table "akdhis_kelanjutanstudi" Column "NIM"
Or
Try To INSERT In Dynamic table FROM table "akdhis_kelanjutanstudi"
Then Left Join On "Dynamic table"
and use some filter in query..

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`$$

Mysql Error 1356 - Views

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.