SQLSTATE[HY000]: General error with MySQL variable in ZF1 - mysql

I have a MySQL query that works perfectly in PhpMyAdmin but throws an SQLSTATE[HY000]: General error when using within Zend Framework 1.12 and its fetchAll() method. Here it is:
SET #csum := 0;
SELECT s1.Date, (#csum := #csum + s1.total) as cumulative_sum
FROM (
SELECT c.datefield AS Date, IFNULL(SUM(subscription_total),0) AS total
FROM subscription s
RIGHT JOIN calendar c
ON c.datefield = DATE(subscription_date)
WHERE (c.datefield BETWEEN
(SELECT MIN(DATE(subscription_date)) FROM subscription)
AND
NOW()
)
GROUP BY DATE
) AS s1
The statement doesn't return any error if I remove the SET statement but I need to set a MySQL variable otherwise cumulative_sum will just be NULL values. Here is the code of the method:
public function findCumulativeCashflow($statut)
{
$db = $this->_getDbTable();
$dbAdapter = new Zend_Db_Adapter_Pdo_Mysql($db->getAdapter()->getConfig());
$sql = '<SQL statement above>';
$statement = $dbAdapter->query($sql);
$rows = $statement->fetchAll();
return $rows;
}
The error points the $rows = $statement->fetchAll(); line, is there another ZF method to use with SET #var := value?
Any ideas would be much appreciated.
Thanks!

As per this question, I need to use another query as fetchAll() cannot handle multiple queries.
I therefore need to set the MySQL variable with $dbAdapter->query('SET #csum := 0;'); and then do the main query.

Related

Convert Sql query to sql CodeIgniter

convert sql query to sql codeigniter
i done try to use this method
How to convert sql query to codeigniter active records
but not working for me...
so i try to post in here
this my sql query
$sql = "SELECT b.id, b.us_id, b.kredit, b.info,u.us_name,
u.us_username, u.us_email, u.us_phone, b.cnt, b.amnt
FROM users u JOIN
(SELECT id, us_id, kredit, info, COUNT(info) cnt, SUM(kredit) amnt
FROM balance_history
GROUP BY info HAVING cnt > 1
) AS b
ON u.us_id = b.us_id
WHERE b.kredit != '0' AND
b.info NOT LIKE '[PERBAIKAN]%' AND
(b.info LIKE 'Transfer saldo%' OR b.info LIKE 'Ket%')
ORDER BY b.id ASC";
thanks before...
If you aren't loaded database globally, you can load it by calling $this->load->database(); The following query may provide the same db call.
$this->db->select('id, us_id, kredit, info, COUNT(info) cnt, SUM(kredit) amnt')
->from('balance_history')
->group_by('info')
->having('cnt > 1');
$subquery = $this->db->get_compiled_select();
$query = $this->db
->select('b.id, b.us_id, b.kredit, b.info,u.us_name,u.us_username, u.us_email, u.us_phone, b.cnt, b.amnt')
->from('users u')
->join('('.$subquery.') b','u.us_id = b.us_id')
->where('b.kredit !=','0', true)
->not_like('b.info', '[PERBAIKAN]', 'after', false, true)
->where('(b.info LIKE "Transfer saldo%" OR b.info LIKE "Ket%")')
->get();

Laravel db::select() returns one string result

I'm trying to make a select using laravel and return with a response-json, i try:
public function verificaQuantidadeAnimaisAprovar(){
$quantidade_pets_aprovar = DB::select('SELECT (SELECT SUM(animal_pendente) FROM cademeupet.animais_adocao) +
(SELECT SUM(animal_pendente) FROM cademeupet.animais_encontrados) +
(SELECT SUM(animal_pendente) FROM cademeupet.animais_perdidos)
FROM DUAL '
);
return response()->json($quantidade_pets_aprovar, 201);
}
In the bd i have this result when i run this query:
but when i run my api in postman i receive:
[{"(SELECT SUM(animal_pendente) FROM cademeupet.animais_adocao) +\r\n
(SELECT SUM(animal_pendente) FROM cademeupet.animais_encontrados) +
\r\n (SELECT SUM(animal_pendente) FROM
cademeupet.animais_perdidos)":"36"}]
I need only the number result query: 36.
How i can fix this?
You are passing a whole SQL expression inside of the select method, which is designed to perform a select sql operation.
You should probably use the raw expression which is designed to handle complete sql queries :
public function verificaQuantidadeAnimaisAprovar(){
$quantidade_pets_aprovar = DB::raw('SELECT (SELECT SUM(animal_pendente) FROM cademeupet.animais_adocao) +
(SELECT SUM(animal_pendente) FROM cademeupet.animais_encontrados) +
(SELECT SUM(animal_pendente) FROM cademeupet.animais_perdidos)
FROM DUAL '
);
return response()->json($quantidade_pets_aprovar, 200);
}
Note : I also changed the http code of your response because 201 (Created) indicates the creation of something, which does not seem to happen here. 200 (Ok) seems more appropriate. Be free to put 201 back if this operation creates something in your database.
Let me know if it helped you :)

MySql Stored Procedure error in WHERE condition

I'm trying to write my first mySql stored procedure and keep on getting an error from the server that I am unable to understand, hope someone will be able to help me fixing it.
What I am doing
I collect some parameters from social networks, and I need to save this data in two different tables. I know that the table schema might not be optimal, but this is something I cannot change at the moment.
The idea is that I call the stored procedure from my server-side code passing in article ID and some other parameters, and the procedure:
Updates the "articles" table
Inserts anew record into the "popularity" tables with some values that are the result of the previous UPDATE
This is the stored procedure I wrote
BEGIN
UPDATE
articles2
SET
fb_shares = n_shares,
fb_comments = n_comments,
fb_reactions = n_reactions,
tw_tweets = #tweets :=(tw_tweets + n_tweets),
tw_retweets = #retweets :=(tw_retweets + n_retweets),
tw_favorites = #favorites :=(tw_favorites + n_favorites),
tw_reach = #reach :=(tw_reach + n_reach),
tw_since_id = n_since_id,
popularity = #popularity :=(
(n_shares * fb_shares_weight) +(
n_comments * fb_comments_weight
) +(
n_reactions * fb_reactions_weight
) +(#tweets * tw_tweets_weight) +(#retweets * tw_retweets_weight) +(
#favorites * tw_favorites_weight
) +(#reach * tw_reach_weight)
),
popularity_updated =(popularity_updated + 1)
WHERE
id = n_id ;
INSERT
INTO
popularity(
article_id,
added,
popularity,
tw_tweets,
tw_reach,
tw_favorites,
tw_retweets,
tw_since_id,
fb_shares,
fb_comments,
fb_reactions
)
VALUES(
n_id,
NOW(), #popularity, #tweets, #reach, #favorites, #retweets, n_since_id, n_shares, n_comments, n_reactions) ;
END
I keep getting an error #1416 - Cannot get geometry object from data you send to the GEOMETRY field and the INSERT is never performed. I suppose that the variables assignment is wrong, but cannot understand how to fix it.
As said, I never wrote a stored procedure before, and since that line looks correct to me, I really cannot understand what's wrong. I cannot exclude that I am trying to do something that should not be done with a stored procedure, but the few examples that I found online makes me think this should be correct...
Thank you in advance,
Simone
Edit:
I got rid of that error, but still the INSERT is not performed... here is the updated stored procedure:
BEGIN
SET #tweets := 0, #retweets := 0, #favorites := 0, #reach := 0, #popularity := 0;
UPDATE
articles2
SET
fb_shares = n_shares,
fb_comments = n_comments,
fb_reactions = n_reactions,
tw_tweets = #tweets :=(tw_tweets + n_tweets),
tw_retweets = #retweets :=(tw_retweets + n_retweets),
tw_favorites = #favorites :=(tw_favorites + n_favorites),
tw_reach = #reach :=(tw_reach + n_reach),
tw_since_id = n_since_id,
popularity = #popularity :=(
(n_shares * fb_shares_weight) +(
n_comments * fb_comments_weight
) +(
n_reactions * fb_reactions_weight
) +(#tweets * tw_tweets_weight) +(#retweets * tw_retweets_weight) +(
#favorites * tw_favorites_weight
) +(#reach * tw_reach_weight)
),
popularity_updated =(popularity_updated + 1)
WHERE
id = n_id ;
SELECT #tweets, #retweets, #favorites, #reach, #popularity;
INSERT
INTO
popularity(
article_id,
added,
popularity,
tw_tweets,
tw_reach,
tw_favorites,
tw_retweets,
tw_since_id,
fb_shares,
fb_comments,
fb_reactions
)
VALUES(
n_id,
NOW(), #popularity, #tweets, #reach, #favorites, #retweets, n_since_id, n_shares, n_comments, n_reactions) ;
END
Check the definition of the popularity table for a field defined with data type GEOMETRY and change to appropriate type.

Calling stored procedure in MySQL takes forever to execute

I have a stored procedure which I'm trying to call, and it takes forever to execute. I have no idea what's wrong. A similar stored procedure in another database executes perfectly. I'm not well-versed with MySQL Workbench, so I don't know if the database settings are different or something.
Following is my stored procedure:
CREATE
DEFINER = `admin`#`%`
PROCEDURE `calculate_daily_coil_moved_by_crane_data`()
BEGIN
set #curr_date = curdate();
set #pre_date = date_add(curdate(), interval -1 day);
set #a_shift_start_ts = concat(#pre_date, ' 06:00:00');
set #a_shift_end_ts = concat(#pre_date, ' 13:59:59');
set #b_shift_start_ts = concat(#pre_date, ' 14:00:00');
set #b_shift_end_ts = concat(#pre_date, ' 21:59:59');
set #c_shift_start_ts = concat(#pre_date, ' 22:00:00');
set #c_shift_end_ts = concat(#curr_date, ' 05:59:59');
SELECT #curr_date,
#pre_date,
#a_shift_start_ts,
#a_shift_end_ts,
#b_shift_start_ts,
#b_shift_end_ts,
#c_shift_start_ts,
#c_shift_end_ts;
#SET DATA
insert into daily_coil_move_by_crane_data_for_report (crane_id, crane_name, date, a_shift, b_shift, c_shift)
select cr.id, cr.name, #pre_date, 0, 0, 0
from yms_phase3.crane cr
where active = 1
order by cr.name;
#----------------------------------------------------------------------------------------------------
#--> COILS MOVED BY CRANE A Shift <--
#----------------------------------------------------------------------------------------------------
SET #shift = 'A';
#FETCH ROW DATA
update daily_coil_move_by_crane_data_for_report
set a_shift = ifnull((select COUNT(*)
FROM yms_phase3.workorder_history in_data
where in_data.crane_id = daily_coil_move_by_crane_data_for_report.crane_id
and current_execution_status IN (6 , 7)
and in_data.pick_ts between #a_shift_start_ts and #a_shift_end_ts
group by in_data.crane_name), 0)
where (a_shift is null or a_shift = 0);
#----------------------------------------------------------------------------------------------------
#--> COILS MOVED BY CRANE B Shift <--
#----------------------------------------------------------------------------------------------------
SET #shift = 'B';
#FETCH ROW DATA
update daily_coil_move_by_crane_data_for_report
set b_shift = ifnull((select COUNT(*)
FROM yms_phase3.workorder_history in_data
where in_data.crane_id = daily_coil_move_by_crane_data_for_report.crane_id
and current_execution_status IN (6 , 7)
and in_data.pick_ts between #b_shift_start_ts and #b_shift_end_ts
group by in_data.crane_name), 0)
where (b_shift is null or b_shift = 0);
#----------------------------------------------------------------------------------------------------
#--> COILS MOVED BY CRANE C Shift <--
#----------------------------------------------------------------------------------------------------
SET #shift = 'C';
#FETCH ROW DATA
update daily_coil_move_by_crane_data_for_report
set c_shift = ifnull((select COUNT(*)
FROM yms_phase3.workorder_history in_data
where in_data.crane_id = daily_coil_move_by_crane_data_for_report.crane_id
and current_execution_status IN (6 , 7)
and in_data.pick_ts between #c_shift_start_ts and #c_shift_end_ts
group by in_data.crane_name), 0)
where (c_shift is null or c_shift = 0);
#----------------------------------------------------------------------------------------------------
#INSERT ALL CRANE ENTRY
insert into daily_coil_move_by_crane_data_for_report (crane_id, crane_name, date, a_shift, b_shift, c_shift)
select -1, 'ALL', #pre_date, SUM(a_shift), sum(b_shift), sum(c_shift)
from daily_coil_move_by_crane_data_for_report
where date = #pre_date
group by date;
#UPDATE TOTAL
update daily_coil_move_by_crane_data_for_report
set total_coils_moved = (a_shift + b_shift + c_shift)
where date = #pre_date;
END
Also tried to execute the query from Java using the following:
jdbcTemplate.execute("CALL calculate_daily_coil_moved_by_crane_data;");
But it gives me the following Exception:
java.sql.SQLException: Lock wait timeout exceeded
Any workaround I can do to solve this?
Please try and edit the configuration file, also search for the same here on stack. There are certain possibilities while checking this out,
Check and edit the config file on Hard drive for MySQL increase the cache capacity and default values as the default values are in KB's the memory allocated is very less and to execute such a big procedure it should at least be some MB.
Increase the connection String timeout, that is by setting up right time in seconds. by default it is 60 seconds, which is very less for executing such a procedure, I think in c# at least we set it to '0' seconds which means that it shall not get timed-out till the query is executed.
If Any left Joins/ inner query please try and check whether the same output is produced in inner joins ? as inner joins are faster than left or right joins.
Add Indexes, have foreign key references properly mapped for faster execution of query.
Hope it works.

Converting MYSQL to Codeigniter

I am trying to convert a MYSQL query to codeigniter and going no wheres real fast. I am trying to convert this query
$conn->prepare("SELECT `id`,`song`,`artist`,`album`,`track`,`mix_name`,`date` FROM `podcasts` where mix_number = (SELECT MAX(mix_number) FROM podcasts) order by track asc");
This is in my model:
//$where = '(SELECT MAX(mix_number)from podcasts)';
$this->db->select('id,song,artist,album,track,mix_name,date, link');
//$this->db->where('mix_number', '(SELECT MAX(mix_number)from podcasts)');
$this->db->order_by('track', 'asc');
$query = $this->db->get('podcasts');
return $query->result();
My problem area is in the where statement. When I comment out the where statement I get the data. Obviously not in the manner I want it.
I am doing it this way becuase my next query(s) will be
("SELECT `id`,`song`,`artist`,`album`,`track`,`mix_name`,`date` FROM `podcasts` where mix_number = **(SELECT MAX(mix_number) FROM podcasts) - 1** order by track asc")
And on down to (SELECT MAX(mix_number) FROM podcasts) - 3
Any thoughts on the proper way of writing the where statement? Thank you for yout time.
Set the third argument of where() to false to prevent CI from altering the string you pass in to the second argument, then you can do the subquery:
return $this->db
->select('id,song,artist,album,track,mix_name,date, link')
->where('mix_number', '(SELECT MAX(mix_number) from podcasts)', false)
->order_by('track', 'asc')
->get('podcasts')
->result();
https://www.codeigniter.com/userguide2/database/active_record.html$this->db->where() accepts an optional third parameter. If you set it to FALSE, CodeIgniter will not try to protect your field or table names with backticks.
For me this produces the following query:
SELECT `id`, `song`, `artist`, `album`, `track`, `mix_name`, `date`, `link`
FROM (`podcasts`)
WHERE mix_number = (SELECT MAX(mix_number) from podcasts) ORDER BY `track` asc
If you are not too particular about using CodeIgniter's Active Record syntax, you can simply use your query as is:
$sql = "SELECT `id`,`song`,`artist`,`album`,`track`,`mix_name`,`date` FROM `podcasts` where mix_number = (SELECT MAX(mix_number) FROM podcasts) order by track asc";
$this->db->query($sql);
and then use $query->result() to get your results.