mysql stored procedure column error - mysql

I receive the following error. But I havent typed count in my stored procedure so why is it giving this error?
CALL updateproposalStatus(1,5) Error Code: 1136. Column count doesn't match value count at row 1
STORED PROCEDURE:
CREATE DEFINER=`root`#`localhost` PROCEDURE `updateProposalStatus`(IN decision INT, IN x INT)
BEGIN
DECLARE adv_id varchar(30);
DECLARE std_id varchar(30);
DECLARE topic varchar(255);
select
a.id INTO adv_id
from
rp_proposal p
inner join rp_adviser a on p.rp_adviser_id = a.id
where p.proposal_id=x;
select
s.id INTO std_id
from
rp_proposal p
inner join rp_student s on p.rp_student_id = s.id
where p.proposal_id=x;
select
p.title INTO topic
from
rp_proposal p
where p.proposal_id=x;
UPDATE rp_proposal_status
SET state_rp_controller =decision
WHERE rp_proposal_id = x;
IF decision = 1 THEN
INSERT INTO rp_indpstudy VALUES (topic,adv_id,std_id);
END IF;
END

It's the column-count (number of columns) that it is complaining about, not about a column named count.
Most likely culprit is the insert statement at the end - make sure that it is consistent with rp_indpstudy's schema.

Related

Error Code 1241 - Operand should contain 1 column(s)

I was creating a procedure and I came across this.
Does anyone know how to solve this?
delimiter $$
create procedure sp_cadastraAluno(
in nome varchar(150),
in chamada varchar(3),
in data date,
in ra varchar(12),
in turma varchar(50),
in cpf varchar(14))
begin
declare x int;
set x = (select * from tb_coordenador inner join tb_professor
on tb_coordenador.cd_coord = tb_professor.cd_coord
inner join prof_turma on
tb_professor.cd_prof = prof_turma.cd_prof
inner join tb_turma on
prof_turma.cd_turma = tb_turma.cd_turma
inner join tb_aluno on
tb_turma.cd_turma = tb_aluno.cd_turma where nm_turma = turma and tb_professor.cd_cpf = cpf);
insert into tb_aluno(nm_aluno, cd_chamada, dt_nascimento, cd_ra, cd_turma) values
(nome, chamada, data, ra, x);
end $$
I need to insert in tb_aluno and for this, I need to pull the code already inserted in tb_turma, but this error appears.
You can't set variable 'x' with multiple columns. try removing select * and replace with the column which you need.

Create stored procedure phpmyadmin

SQL says I have syntax error near '' at line 3. Please help
My objective is to calculate the sum of medications' prices
Here is my SQL code from phpmyadmin:
CREATE PROCEDURE spMEDICATION_FEE(IN PatientID CHAR(9))
BEGIN
DECLARE Sum2 INT;
DECLARE Sum3 INT;
SET Sum2 = (
SELECT SUM(MPRICE)
FROM USES_EXAM INNER JOIN MEDICATION ON USES_EXAM.MID = MEDICATION.MID
WHERE PID_OUT = PatientID);
SET Sum3 = (
SELECT SUM(MPRICE)
FROM USES_TREAT INNER JOIN MEDICATION ON USES_TREAT.MID = MEDICATION.MID
WHERE PID_IN = PatientID);
IF Sum2 IS NULL THEN
SET Sum2 = 0;
IF Sum3 IS NULL THEN
SET Sum3 = 0;
SELECT Sum2+ Sum3 AS 'Total fee';
END
If you are using SQL tab of phpymadmin to run this query, you should define a delimiter instead of ;. For example, try this:
DELIMITER $$
paste your create procedure code here
$$

How to add salary from two tables in stored procedure

I want to add the salary from two tables in stored procedure on the basis of id column:
DDl:
create table salary1 (id varchar(20), salary varchar(20));
create table salary2 (id varchar(20), salary varchar(20));
DML:
insert into salary1 values('1', '100');
insert into salary1 values('2', '200');
insert into salary2 values('1', '10');
insert into salary2 values('2', '10');
Database: mysql
Output should like this:
id total_sal
1 110
2 210
My stored procedure look like:
CREATE PROCEDURE totalSal()
BEGIN
DECLARE tbl1_id varchar(30);
DECLARE tbl1_sal varchar(30);
DECLARE tbl2_id varchar(30);
DECLARE tbl2_sal varchar(30);
DECLARE total_sal varchar(30);
DECLARE c1 CURSOR FOR SELECT * FROM salary1;
DECLARE c2 CURSOR FOR SELECT * FROM salary2;
-- Open first cursor
OPEN c1;
LOOP
FETCH c1 INTO tbl1_id, tbl1_sal;
-- Open second cursor
OPEN c2;
LOOP
FETCH c2 INTO tbl2_id, tbl2_sal;
IF tbl1_id = tbl2_id THEN
set total_sal := tbl1_sal + tbl2_sal;
ELSE
set total_sal := tbl_sal;
END IF;
END LOOP;
CLOSE c2;
END LOOP;
CLOSE c1;
end $$
It got's successfully compiled, but when i am running the procedure i am getting the below error:
ERROR 1329 (02000): No data - zero rows fetched, selected, or processed
I have also used the DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; in my procedure. but still my problem is unresolved.
If someone can solve this problem in oracle, that would also help me.
Note : I cannot perform join operation on these tables. Because of a few performance issues.
Thanks in advance !!!
Solution 1:
Using collection and only one iteration of 2 loop
You should consider to fix your performance issue on join. Performing loop is slower than a set base approach in most case.
If I follow your logic, what you realy want is to loop trough all the salary2 table for each salary1 row in order to found the right ID => millions of loop.
You can consider doing 2 separated loop and store data inside and indexed array. ( the key will be the tlb1_id).
If the key exist : sum the salary values, if not exist insert it inside the array.
At the end of the procedure, just select the array as table.
Solution 2:
Using a join on integer indexed columns
you can add a new integer column on each table
Populate this column with the casted value of the ID column
Add an index on these columns on each tables
After that you will be able to perform a join
Have a look at this fiddle http://sqlfiddle.com/#!9/c445de/1 , it can be time consuming to perform theses step and disk space consumuming to add a new columns and indexes but the join operation may be faster than before.
You can do something like this... I have moved the second cursor inside the loop so that it only goes over the id's from table 1. This should help the logic for the procedure but still I would recommend trying to figure out how to fix the join to get the results as that seems like an easier way and should be much faster if done correctly.
CREATE PROCEDURE totalSal()
BEGIN
DECLARE tbl1_id varchar(30);
DECLARE tbl1_sal varchar(30);
DECLARE tbl2_id varchar(30);
DECLARE tbl2_sal varchar(30);
DECLARE total_sal varchar(30);
DECLARE c1 CURSOR FOR SELECT * FROM salary1;
-- Open first cursor
OPEN c1;
LOOP
FETCH c1 INTO tbl1_id, tbl1_sal;
SELECT COUNT(*) INTO v_rowcount FROM salary2 WHERE id = tbl1_id;
IF v_rowcount > 0 THEN
Begin
DECLARE c2 CURSOR FOR SELECT * FROM salary2 WHERE id = tbl1_id;
-- Open second cursor
OPEN c2;
LOOP
FETCH c2 INTO tbl2_id, tbl2_sal;
IF tbl1_id = tbl2_id THEN
set total_sal := tbl1_sal + tbl2_sal;
ELSE
set total_sal := tbl_sal;
END IF;
END LOOP;
CLOSE c2;
END IF;
END
END LOOP;
CLOSE c1;
end $$
Well you asked for an answer without JOIN, but that seemed arbitrary, so here's an answer with JOIN.
SELECT
sums1.id
, S1Sum + S2Sum AS SalarySum
FROM (SELECT id, SUM(CAST(salary AS int)) AS S1Sum
FROM salary1
GROUP BY id) sums1
JOIN (SELECT id, SUM(CAST(salary AS int)) AS S2Sum
FROM salary2
GROUP BY id) sums2
ON sums1.id = sums2.id
I am guessing your performance is bad because all of your columns are varchar when they should be int or numeric. But we don't have much to go on so hopefully this helps you come to a solid solution.
Also the post was edited to add both MySQL and Oracle tags so it's difficult to determine what the syntax should be...

MySQL: join to SELECT statement issue

I've created the following stored procedure:
CREATE PROCEDURE `sp_DBR_Subbie_Cert_Input`(inPlot_ID varchar(25), inSubbie varchar(25), inCertDate date, inCertDetails varchar(50), inCertGross float ) BEGIN
SELECT inPlot_ID as 'Plot[Unit]', inSubbie as 'Subcontractor[inSub_ID]', inCertDate as 'Date[inC_Date]', inCertDetails as 'Details[inC_Det]', inCertGross as 'Gross[inC_Gross]', a.tblCert_Number as 'Prev. Cert#', a.tblCert_Gross as 'Prev Gross[inC_Prev]'
FROM hilmark.tblcertificates_j a
JOIN
(SELECT max(tblcertificates_j.tblCert_ID) as MaxCertID,
tblcertificates_j.tblCert_XID456 as MaxSubbie, tblcertificates_j.tblCert_XIDJob as MaxPlot
FROM hilmark.tblcertificates_j
GROUP BY tblcertificates_j.tblCert_XIDJob) x
WHERE x.MaxCertID=a.tblCert_ID AND x.MaxPlot=inPlot_ID AND x.MaxSubbie=inSubbie;
END $$
What I am trying to achieve is to allow a user to enter a new invoice for a supplier for a site. The query retrieves the last invoice for that supplier and that site. This works great except when this is the first invoice for that supplier on that site - nothing is returned. What I really need is a left outer join but in my code if I substitute the join with a left join I get a syntax error.
Where am I going wrong here?
I declared a variable called Max_CerT_ID and set it's value to the Cert_ID from the table or to zero if it's a completely new supplier. I then use this variable in case statements.
DROP PROCEDURE IF EXISTS sp_DBR_Subbie_Cert_Input
$$
CREATE PROCEDURE `sp_DBR_Subbie_Cert_Input`(inPlot_ID varchar(25), inSubbie varchar(25), inCertDate date, inCertDetails varchar(50), inCertGross float )
BEGIN
declare Max_Cert_Id int(11);
set Max_Cert_Id=0;
select max(y.tblCert_ID) into Max_Cert_ID from
hilmark.tblcertificates_j y
where y.tblCert_XIDJob=inPlot_ID and y.tblCert_XID456=inSubbie
group by y.tblCert_XIDJob, y.tblCert_XID456 ;
select 'dbr.colstyle',6,'%0.0F';
select 'dbr.colstyle',7,'%0.0F';
select 'dbr.colstyle',8,'%0.0F';
select inPlot_ID as 'Plot[Unit]',
inSubbie as 'Subcontractor[inSub_ID]',
inCertDate as 'Date[inC_Date]',
case
when Max_Cert_Id=0 then 1
else (select a.tblCert_Number from hilmark.tblcertificates_j a where a.tblCert_ID=Max_Cert_ID)+1
end as 'Cert#',
upper(inCertDetails) as 'Details[inC_Det]',
inCertGross as 'Gross[inC_Gross]',
case
when Max_Cert_Id=0 then 0
else (select a.tblCert_Gross from hilmark.tblcertificates_j a where a.tblCert_ID=Max_Cert_ID)
end as 'Prev. Gross',
case
when Max_Cert_Id=0 then inCertGross
else inCertGross-(select a.tblCert_Gross from hilmark.tblcertificates_j a where a.tblCert_ID=Max_Cert_ID)
end as 'Change in WIP';
END
$$
Try writing the query as:
SELECT inPlot_ID as `Plot[Unit]`, inSubbie as `Subcontractor[inSub_ID]`,
inCertDate as `Date[inC_Date]`, inCertDetails as `Details[inC_Det]`,
inCertGross as `Gross[inC_Gross]`, c.tblCert_Number as `Prev. Cert#`,
c.tblCert_Gross as `Prev Gross[inC_Prev]`
FROM hilmark.tblcertificates_j c LEFT JOIN
(SELECT max(c.tblCert_ID) as MaxCertID, c.tblCert_XID456 as MaxSubbie,
c.tblCert_XIDJob as MaxPlot
FROM hilmark.tblcertificates_j c
GROUP BY c.tblCert_XIDJob
) cmax
WHERE cmax.MaxCertID = c.tblCert_ID AND cmax.MaxPlot = c.inPlot_ID AND cmax.MaxSubbie = c.inSubbie;
Some notes:
I doubt this really does what you want, because MaxSubbie has an indeterminate value. But you save the query works. Why do you need both comparisons?
When using table aliases, make them abbreviations for the table so the query is easier to read.
Only use single quotes for string and date constants.

Mysql stored procedure syntax

I am trying to write simple mysql stored procedure and it seems that I can't get it right, so far I have
delimiter //
create procedure addRecord(_login varchar(15),_artist varchar(50),_record varchar(50))
begin
declare dbArtist varchar(50);
delcare dbRecord varchar(50);
set dbArtist = (select artistname from artists where lower(artistname) = lower(_artist));
set dbRecord=(select recordname from records where lower(recordname)=lower(_record));
if not exists (select * from Artists where lower(artistname)=lower(_artist)) then
begin
INSERT INTO `Artists`(`ArtistName`) VALUES (_artist);
set dbArtist=_artist;
end
if not exists (select * from Records as R inner join Artists as A on R.ArtistId=A.ArtistId where lower(R.RecordName)=lower(_record) and A.ArtistName=dbArtist) then
begin
INSERT INTO `Records`(`ArtistId`, `RecordName`) VALUES ((select artistid from artists where artistname=dbArtist),_record);
set dbRecord=_record;
end
end
but I get syntax error in line 4:
#1064 - You have an error in your SQL syntax; check the manual that corresponds
to your MySQL server version for the right syntax to use near 'dbRecord varchar(50);
set dbArtist = (select artistname from artists where lowe' at line 4
this message error was returned to me by phpMyAdmin, can anyone tell me why do I get an error?
edit: modified version, still not good
delimiter //
create procedure addRecord(_login varchar(15),_artist varchar(50),_record varchar(50))
begin
declare dbArtist varchar(50);
declare dbRecord varchar(50);
set dbArtist = (select artistname from artists where lower(artistname) = lower(_artist));
set dbRecord=(select recordname from records where lower(recordname)=lower(_record));
if not exists (select * from Artists where lower(artistname)=lower(_artist)) then
begin
INSERT INTO `Artists`(`ArtistName`) VALUES (_artist);
set dbArtist=_artist;
end
if not exists
(select * from Records as R inner join Artists as A on R.ArtistId = A.ArtistId where lower(R.RecordName)=lower(_record) and A.ArtistName=dbArtist)
then
begin
INSERT INTO `Records`(`ArtistId`, `RecordName`) VALUES ( (select artistid from artists where artistname=dbArtist) ,_record);
set dbRecord=_record;
end
end
now error in line 14 and message:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'if not exists (select * from Records as R inner join Artists as A on R.ArtistId' at line 14
The problem is that you misspelled DECLARE:
delcare dbRecord varchar(50);
UPDATE: For your next error, the problem is your illegal use of NOT EXISTS.
Within a stored procedure the proper approach is to count the existing rows, and then conditionally insert a value if the count is 0.
Something like this:
SELECT COUNT(*)
INTO #v_row_count
FROM Artists
WHERE LOWER(artistname)=LOWER(_artist);
IF (#v_row_count = 0)
THEN
INSERT INTO `Artists`(`ArtistName`) VALUES (_artist);
set dbArtist=_artist;
END IF;
P.S. To avoid poor performance on on your select query, you should consider using a collation that is not case-sensitive so you don't need to apply the LOWER() function to the artistname column.