I have 3 Tables : Venta , Factura, Producto . So I'm trying to create a Trigeer that insert values on table "Factura" and udpate a value on "Producto" when inserting on Venta. This is my first Trigger and I'dont know what I'm doing wrong, I think maybe I'm not getting the idea on how to declare variables ?. I'll appreciate any light on this .
I've modified the code as I did understand. Now I'm getting a syntax error on the line were de UPDATE instruction is. By the way, the tables are:
mysql> describe Producto;
+------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| Cod_Prod | varchar(8) | NO | PRI | NULL | |
| Nom_Prod_P | varchar(16) | NO | | NULL | |
| Precio_P | decimal(9,2) | NO | | NULL | |
| Cantidad_P | int(6) | NO | | NULL | |
+------------+--------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
mysql> describe Venta;
+--------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id_Venta | varchar(9) | NO | PRI | NULL | |
| Fecha_V | date | NO | | NULL | |
| Nom_Cli_V | varchar(24) | NO | | NULL | |
| Rut_Cli_V | varchar(12) | NO | | NULL | |
| Dir_Cli_V | varchar(16) | NO | | NULL | |
| Nom_Prod_V | varchar(16) | NO | | NULL | |
| Precio_V | decimal(9,2) | NO | | NULL | |
| Cant_Prod_V | int(6) | NO | | NULL | |
| Forma_Pago_V | varchar(12) | NO | | NULL | |
+--------------+--------------+------+-----+---------+-------+
9 rows in set (0.00 sec)
mysql> describe Factura;
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| Num_Fac | int(11) | NO | PRI | NULL | auto_increment |
| Fecha_F | date | NO | | NULL | |
| Nom_Cli_F | varchar(24) | NO | | NULL | |
| Rut_Cli_F | varchar(12) | NO | | NULL | |
| Dir_Cli_F | varchar(16) | NO | | NULL | |
| Nom_Prod_F | varchar(24) | NO | | NULL | |
| Cant_Prod_F | int(6) | NO | | NULL | |
| Neto | decimal(9,2) | NO | | NULL | |
| IVA | decimal(9,2) | NO | | NULL | |
| Total | decimal(9,2) | NO | | NULL | |
| Forma_Pago_F | varchar(12) | NO | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
11 rows in set (0.00 sec)
DELIMITER $$
CREATE TRIGGER Genera_Factura_Before
BEFORE INSERT
ON TuOficina.Venta
FOR EACH ROW
BEGIN
DECLARE calc_iva decimal(9,2);
DECLARE calc_neto decimal(9,2);
DECLARE gran_total decimal(9,2);
DECLARE prod_descuento int(6);
SET calc_neto = new.Precio_V * new.Cant_Prod_V;
SET calc_iva = calc_neto / 0.19;
SET gran_total = calc_neto + calc_iva;
SET prod_descuento = new.Cant_Prod_V - Cantidad_P;
INSERT INTO Factura(Fecha_F, Nom_Cli_F, Rut_Cli_F, Dir_Cli_F, Nom_Prod_F, Cant_Prod_F, Neto, IVA, Total, Forma_Pago_F) VALUES (Fecha_V, new.Nom_Cli_V, new.Rut_Cli_V, new.Dir_Cli_V, new.Nom_Prod_V, new.Cant_Prod_V, calc_neto, calc_iva, gran_total, new.Forma_Pago_V);
UPDATE Producto SET Cantidad_P = prod_descuento WHERE Nom_Prod_P = new.Nom_Prod_P;
END$$
A couple of issues stand out immediately...
In MySQL numeric literal, the decimal point character must be a period (dot) not a comma.
SET iva = neto / 0,19 ;
^
In an INSERT trigger, there is no OLD. value for a column in the table. That is valid only in an UPDATE or DELETE trigger.
SET prod_descuento = new.Cant_Prod_V - old.Cant_Prod_P;
^^^^
Also, beware of columns and variables with the same name, in the context of a SQL statement. When its possible a reference could be to a variable or a column, MySQL will resolve the reference to be to the column.
Related
On my authorization, i was looking user by his social id:
select * from users where yandex_id = 65250508;
And result is very bad: 1 row in set (11.25 sec)
Count of this table:
select count(id) from users;
+-----------+
| count(id) |
+-----------+
| 1852446 |
+-----------+
Also there is explain of my query:
explain select * from users where yandex_id = 65250508;
+------+-------------+-------+------+---------------------------------+------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------------------------+------+---------+------+---------+-------------+
| 1 | SIMPLE | users | ALL | UNIQ_1483A5E988FDD79D,yandex_id | NULL | NULL | NULL | 1820017 | Using where |
+------+-------------+-------+------+---------------------------------+------+---------+------+---------+-------------+
and describe of table:
describe users;
+-------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| ts | int(10) unsigned | NO | MUL | NULL | |
| last_ts | int(10) unsigned | NO | MUL | NULL | |
| last_mail | int(10) unsigned | NO | | NULL | |
| photo | varchar(32) | YES | | NULL | |
| name | varchar(48) | YES | | NULL | |
| email | varchar(48) | YES | UNI | NULL | |
| state | smallint(6) | NO | MUL | NULL | |
| ip | bigint(20) unsigned | NO | | NULL | |
| gender | varchar(1) | NO | | NULL | |
| facebook_id | varchar(64) | YES | UNI | NULL | |
| mailru_id | varchar(64) | YES | UNI | NULL | |
| vk_id | varchar(64) | YES | UNI | NULL | |
| yandex_id | varchar(64) | YES | UNI | NULL | |
| google_id | varchar(64) | YES | UNI | NULL | |
| roles | longtext | YES | | NULL | |
| is_active | tinyint(1) | NO | MUL | 1 | |
+-------------+---------------------+------+-----+---------+----------------+
17 rows in set (0.00 sec)
Try USE INDEX(update_index) in your query explicitly.
Sometimes the optimizer makes wrong choice in selecting the index because of which the query is becoming slow.
I have resolved my issue. So, problem was in that i'm using in where integer value, but my field vas defined as varchar, so when i have changed searching id to string, it starts working perfect
MariaDB [hrabr]> select * from users force index(yandex_id) where yandex_id = 65250508;
1 row in set (13.81 sec)
and with string:
MariaDB [hrabr]> select * from users force index(yandex_id) where yandex_id = '65250508';
1 row in set (0.00 sec)
I hope it will help someone!
How can I select all rows from the 'trade' table that have a 'ticker_id' field equal to the 'id' field of a row from the 'ticker' table, that has a 'name' field equal to 'MSFT'?
The 'trade.ticker_id' field is a foreign key to the 'ticker.id' field.
Is this a bad design if I want filter a lot of 'trade' rows?
mysql> describe ticker;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(64) | NO | | NULL | |
| long_name | varchar(250) | YES | | NULL | |
| exchange_id | int(11) | YES | MUL | NULL | |
+-------------+--------------+------+-----+---------+----------------+
4 rows in set (0,00 sec)
mysql> describe trade;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| time | datetime | NO | | NULL | |
| price | float | NO | | NULL | |
| quantity | int(11) | NO | | NULL | |
| source | varchar(64) | YES | | NULL | |
| buyer | varchar(64) | YES | | NULL | |
| seller | varchar(64) | YES | | NULL | |
| initiator | varchar(64) | YES | | NULL | |
| ticker_id | int(11) | YES | MUL | NULL | |
+-----------+-------------+------+-----+---------+----------------+
9 rows in set (0,00 sec)
SELECT * FROM trade TR
LEFT JOIN ticker TI ON TR.ticker_id = TI.id
WHERE TI.name = "MSFT"
I have the following existing table in a mysql database:
+---------------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+---------------+------+-----+---------+----------------+
| f1 | int(11) | NO | PRI | NULL | auto_increment |
| field2 | int(11) | NO | MUL | NULL | |
| field3 | int(11) | YES | | NULL | |
| field4 | int(11) | YES | | NULL | |
| field6 | varchar(64) | YES | | NULL | |
| field7 | varchar(16) | YES | | NULL | |
| field8 | varchar(32) | YES | | NULL | |
| field9 | varchar(128) | YES | | NULL | |
| field10 | varchar(128) | YES | | NULL | |
| field11 | varchar(128) | YES | | NULL | |
| field12 | varchar(64) | YES | | NULL | |
| field13 | varchar(32) | YES | | NULL | |
| field14 | varchar(32) | YES | | NULL | |
| field15 | int(11) | YES | MUL | NULL | |
| field16 | date | YES | | NULL | |
| field17 | date | YES | | NULL | |
| field18 | int(11) | YES | MUL | NULL | |
| field19 | varchar(64) | YES | | NULL | |
| field20 | varchar(64) | YES | | NULL | |
| field21 | varchar(16) | YES | | NULL | |
| field22 | varchar(20) | YES | | NULL | |
| field23 | varchar(1000) | YES | | NULL | |
| field24 | int(11) | NO | MUL | NULL | |
| field25 | int(11) | NO | | 0 | |
| field26 | decimal(19,2) | YES | | 0.00 | |
| field27 | decimal(19,2) | YES | | 0.00 | |
| field28 | int(11) | YES | MUL | NULL | |
| field29 | int(11) | YES | MUL | NULL | |
| field30 | varchar(128) | YES | | NULL | |
| field31 | varchar(128) | YES | | NULL | |
| field32 | varchar(16) | YES | | NULL | |
| field33 | int(11) | YES | | NULL | |
| field34 | int(11) | YES | | NULL | |
| field35 | varchar(128) | YES | | NULL | |
| field36 | int(11) | YES | MUL | NULL | |
| field37 | int(11) | YES | | NULL | |
+---------------------+---------------+------+-----+---------+----------------+
I try the following statement to add another row and I'm getting the following error:
ERROR 1136 (21S01): Column count doesn't match value count at row 1
Here are the ways I've tried to insert the row into the table:
insert into table (Field, Type, Null, Key, Default, Extra) VALUES ("contract_expiration", "date", "YES", "", "NULL", "");
insert into table VALUES ('contract_expiration','date','YES','','NULL','');
Both return the same error. There are no triggers on the table, I'm not sure what's going on.
Any suggestions? I'm relatively new to mysql administration, I know a bit but this has me stumped and searches for solutions have turned up nothing.
Any help that could be provided would be MUCH appreciated!
NULL is not a valid field name in:
insert into `table`(Field, Type, Null, Key, Default, Extra)
VALUES ("contract_expiration", "date", "YES", "", "NULL", "");
And Key and default are reserved words. Try this:
insert into `table`(Field, `Type`, `Null`, `Key`, `Default`, Extra)
VALUES ("contract_expiration", "date", "YES", "", "NULL", "");
mysql> desc classroom;
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| clId | int(11) | NO | PRI | NULL | auto_increment |
| clFName | varchar(30) | NO | | NULL | |
| clSName | varchar(10) | NO | | NULL | |
| clCapc | int(3) | NO | | NULL | |
+---------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> select * from classroom;
+------+------------+---------+--------+
| clId | clFName | clSName | clCapc |
+------+------------+---------+--------+
| 1 | Classroom1 | cl1 | 100 |
| 2 | 2 | 2 | 2 |
| 3 | 3f | 3s | 3 |
| 4 | 3f | 3s | 3 |
| 5 | class4 | class4 | 100 |
+------+------------+---------+--------+
5 rows in set (0.00 sec)
I also have same error
mysql> insert into classroom values('Gudadhe', 'Akash', 20);
ERROR 1136 (21S01): Column count doesn't match value count at row 1
This error can be solved by specifying column names before inserting directly as follows
By writing classroom(clFName, clSName, clCapc) we are specifying columns into which we want to insert values
mysql> insert into classroom(clFName, clSName, clCapc) values('Gudadhe', 'Akash', 20);
Query OK, 1 row affected (0.06 sec)
I had a similar case, where I took the table definition from a dev server and the data from a live server, and it turned out that they were actually not quite the same.
The way I found out the difference was (there are probably smarter ways to do it, but this is how I did it):
SHOW CREATE TABLE mytable;
I ran this on all 3 cases (live database, dev database, and new database I created using CREATE TABLE xxx like xxx).
Then I simply compared the 3 and found that the live and dev had a different set of columns, so I simply ran
ALTER TABLE xxx DROP yyy;
until the new table was the same as the table the dump was from; then I could import data.
I've been trying to set up a trigger in mysql to no avail.
Here are the tables related to it:
mysql> describe ttloki;
+-------------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------+------+-----+-------------------+-----------------------------+
| Lokinumero | int(11) | NO | PRI | NULL | auto_increment |
| Ttnumero | int(11) | NO | MUL | NULL | |
| Kirjausaika | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------------+-----------+------+-----+-------------------+-----------------------------+
3 rows in set (0.00 sec)
mysql> describe tyontekija;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| Numero | int(11) | NO | PRI | NULL | |
| Sukunimi | varchar(40) | NO | | NULL | |
| Etunimi | varchar(40) | NO | | NULL | |
| Osasto | int(11) | YES | MUL | NULL | |
| Lahios | varchar(40) | YES | | NULL | |
| Postino | varchar(5) | NO | MUL | NULL | |
| Puhelin | varchar(16) | YES | | NULL | |
| Palkka | int(11) | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
8 rows in set (0.00 sec)
My last tryout trigger is this:
create trigger uusitt
after insert on TYONTEKIJA
for each row
insert into TTLOKI(Ttnumero) values
(old.TYONTEKIJA.Numero);
Whenever I try to insert into TYONTEKIJA it gives me errors about whatever is in values in the trigger.
mysql> insert into TYONTEKIJA(Numero,Sukunimi,Etunimi,Osasto,Lahios,Postino,Puhelin,Palkka) values
-> (220000, "Saarikoski", "Pekka", 5, "Umpikuja 1", "02760", "060-7358461", 3000);
ERROR 1054 (42S22): Unknown column 'old.TYONTEKIJA.Numero' in 'field list'
I don't understand how to set up this kind of a trigger correctly.
What should I change to fix this?
When you insert a value, you cannot use old identifier because there is no old values yet. Maybe you mean, new.Numero?
mysql> describe posts;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | | NULL | |
| title | varchar(255) | NO | | NULL | |
| body | text | YES | | NULL | |
| category_id | int(11) | NO | | NULL | |
| tags | varchar(50) | NO | | NULL | |
| mark | tinyint(4) | NO | | 1 | |
| created | datetime | YES | | NULL | |
| modified | datetime | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
9 rows in set (0.00 sec)
mysql> describe comments;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| post_id | int(11) | NO | MUL | NULL | |
| name | varchar(255) | NO | | NULL | |
| email | varchar(255) | NO | | NULL | |
| body | varchar(500) | NO | | NULL | |
| mark | tinyint(4) | NO | | 1 | |
| created | datetime | YES | | NULL | |
| modified | datetime | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)
I need the posts.title which has more comments limit 10 or there is no limit.
What i tried so far=>
$conditions=array(
'fields'=>array('Comment.post_id'),
'group'=>array('Comment.post_id'),
'order'=>array('count(Comment.post_id) DESC'),
'limit'=>'5'
);
$mostComments=$this->Post->Comment->find('all',$conditions);
$postId=array();
foreach($mostComments as $val){
array_push($postId,$val['Comment']['post_id']);
}
$postsWithmostComments=$this->Post->find('all',array('conditions'=>array('Post.id '=>$postId)) );
$this->set('postsWithmostComments',$postsWithmostComments);
Can anyone post sql query to find posts.it,posts.title with more comments? Or any cakephp find command?
Try this
$contain = array('Comment');
$posts = $this->Post->find('all', array('contain'=>$contain));
$posts_with_comments = array_filter($posts, 'ten_or_more');
uasort($posts_with_comments, 'order_by_comment_count');
$this->set('postsWithmostComments',$posts_with_comments);
function order_by_comment_count($a, $b) {
if (count($a['Comment'] == $b['Comment'])
return 0;
return ($a['Comment'] < $b['Comment']) ? -1 : 1;
}
function ten_or_more($post) {
return (count($post['Comment']) >= 10);
}