Incorrect syntax near 'INSERT' and 'WHERE' - sql-server-2008

I can't figure out what's wrong with my stored procedure.
CREATE PROCEDURE duplicatecheck2
#QmemberID INT,
#InputDate DATE
AS
INSERT INTO tbl_availableMembers
SELECT memberId
FROM tbl_attendancesheet
WHERE MemberId = #QmemberId
AND [date] = #InputDate
AND [clockin] IS NOT NULL
AND [clockout] IS NULL
UNION
INSERT INTO tbl_availableMembers
SELECT memberId
FROM tbl_attendancemembers
WHERE memberId NOT IN (SELECT memberId
FROM tbl_attendanceSheet)
WHERE date = #InputDate)
I get these errors:
Msg 156, Level 15, State 1, Procedure duplicatecheck2, Line 14
Incorrect syntax near the keyword 'Insert'.
Msg 156, Level 15, State 1, Procedure duplicatecheck2, Line 18
Incorrect syntax near the keyword 'WHERE'.
My other stored procedure that union has worked in it:
CREATE PROCEDURE duplicateCheck
#inputdate DATE
AS
BEGIN
DELETE FROM tbl_availableMembers
INSERT INTO tbl_availableMembers
SELECT memberId
FROM tbl_attendancemembers
WHERE memberId NOT IN (SELECT memberId FROM tbl_attendanceSheet)
UNION
SELECT memberId
FROM tbl_attendancemembers
WHERE memberId IN (SELECT memberId
FROM tbl_attendanceSheet
GROUP BY memberId, date
HAVING COUNT(*) <= 1 AND date = #inputdate)
END

Get rid of the "UNION". The stored procedure can just run two insert statements.
Noel

You cannot apply the UNION to two INSERT statements (as in your first code snippet) - but you can apply it to two SELECT statements (as in your second code sample)
By #marc_s

Related

Operand Should Contain 1 Column(s), Trying to generate volunteer data

I can't seem to troubleshoot my problem.
My stored procedure:
CREATE DEFINER=`myschoolusername`#`%` PROCEDURE `generate_volunteers`(in nfolks int)
BEGIN
set #i=0;
while #i < nfolks do
insert into Volunteer(firstname, lastname, dateofbirth)
values (((floor(1+(rand()*(4-1))), "Fred", "Wang", "Fatimah", "Marcella")),
((floor(1+(rand()*(3-1))), "Kaser", "Fang", "Kumar")),
DATE_ADD('1965-01-01', INTERVAL rand()*200000 DAY));
set #i = #i+1;
end while;
END
Additionally, here is my volunteer table in my MYSQL script:
drop table if exists Volunteer;
create Table Volunteer(
member_num int not null auto_increment primary key,
firstname varchar(20) not null,
lastname varchar(20) not null,
dateofbirth date not null
);
I am trying to insert 500 lines into this table, however error 1305 is coming up.
Any help is heavily appreciated, I am quite unsure of where to go from this point.
This logic doesn't do anything:
(floor(1+(rand()*(4-1))), "Fred", "Wang", "Fatimah", "Marcella"))
Although not the most efficient, this should be fine for 500 rows:
insert into Volunteer(firstname, lastname, dateofbirth)
select f.firstname, l.lastname,
DATE_ADD('1965-01-01', INTERVAL rand()*200000 DAY)
from (select 'Fred' as firstname union all
select 'Wang' union all
select 'Fatimah' union all
select 'Marcella'
) f cross join
(select 'Kaser' as lastname union all
select 'Fang' union all
select 'Kumar'
) l
order by rand()
limit 1;
I think you are actually trying to write:
insert into Volunteer(firstname, lastname, dateofbirth)
select elt(floor(rand() * 4) + 1,
'Fred', 'Wang', 'Fatimah', 'Marcella'
) as firstname,
elt(floor(rand() * 3) + 1,
'Kaser', 'Fang', 'Kumar'
) as lastname,
DATE_ADD('1965-01-01', INTERVAL rand()*200000 DAY);

Counting DISTINCT values in T-SQL

I am trying to count the number of distinct email addresses in a view, but I can't figure out the syntax... Here's what I have:
BEGIN
SELECT COUNT(*) AS UserCount FROM (
SELECT DISTINCT EmailAddress
FROM viewCohortsAuthorizedByContractor
WHERE (ListAccess = 1) AND (ContractorId = #id)
)
END
The inner select works fine, but if I try adding the COUNT, I get the following error: Msg 156, Level 15, State 1, Procedure rptContractorUsersWithListUserCount, Line 23 [Batch Start Line 15]
Incorrect syntax near the keyword 'END'.
I'm sure there's a simple solution, I just can't figure it out...
You don't need the subquery. Try this:
SELECT count(DISTINCT EmailAddress) as UserCount
FROM viewCohortsAuthorizedByContractor
WHERE (ListAccess = 1) AND (ContractorId = #id)
BEGIN
SELECT COUNT(*) AS UserCount FROM (
SELECT DISTINCT EmailAddress
FROM viewCohortsAuthorizedByContractor
WHERE (ListAccess = 1) AND (ContractorId = #id)
)A -----give a name for result set
END

Storing MySQL query as function

I'm new to MySQL functions. I Created a function:
CREATE FUNCTION `tems`.`<function_name>`(IN bid INT, IN cid INT)
RETURNS INT(10)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE min_no INT;
SELECT COALESCE(min(number),1)
FROM
(SELECT r1.number -1 AS number, r1.branch_id, r1.course_id
FROM `Room` AS r1
LEFT JOIN `Room` AS r2
ON r1.branch_id = r2.branch_id
AND r1.course_id = r2.course_id
AND (r1.number - 1) = r2.number
WHERE r1.number > 1 AND r2.number IS NULL
UNION ALL
SELECT max(number) + 1, branch_id, course_id
FROM `Room`
GROUP BY branch_id, course_id) AS q
WHERE branch_id=bid AND course_id=cid
GROUP BY branch_id, course_id
INTO min_no;
RETURN (min_no);
END;
And I want to get bid, cid and return the select value, but I'm getting an error message:
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 'IN bid INT, IN cid INT)
RETURNS INT(10)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS ' at line 1
What am I doing wrong?
Use a DELIMITER like below along with removing the two part identifier. Just declare the function name.
DELIMITER $$
CREATE FUNCTION MyTestFunc (bid INT, cid INT)
RETURNS INT(10)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE min_no INT;
SELECT COALESCE(min(number),1)
FROM
(SELECT r1.number -1 AS number, r1.branch_id, r1.course_id
FROM `Room` AS r1
LEFT JOIN `Room` AS r2
ON r1.branch_id = r2.branch_id
AND r1.course_id = r2.course_id
AND (r1.number - 1) = r2.number
WHERE r1.number > 1 AND r2.number IS NULL
UNION ALL
SELECT max(number) + 1, branch_id, course_id
FROM `Room`
GROUP BY branch_id, course_id) AS q
WHERE branch_id=bid AND course_id=cid
GROUP BY branch_id, course_id
INTO min_no;
RETURN (min_no);
END$$
DELIMITER ;

Table function throwing ERROR: there is no parameter $1

I have the following query which I'd like to turn into a function. I have written the SQL for 1 company_id = 26304
SELECT t.* FROM crosstab(
$$
select company_id, row_number() OVER (ORDER BY year DESC) AS rn2, id
from
(select i.company_id, year, f.id, f.created_at,
row_number() OVER (PARTITION BY year
ORDER BY year DESC, f.created_at DESC NULLS LAST) AS rn
from
public.interactions i
inner join public.financials f on f.interaction_id = i.id
where company_id = 26304
) t1
where rn= 1 limit 3
$$
) AS t (company_id int, financial_id_1 int, financial_id_2 int, financial_id_3 int);
This SQL statement pivots my dataset and returns the following as expected:
company_id financial_id_1 financial_id_2 financial_id_3
26304 6796 6795 6786
However, when I try to turn this into a table function it throws the following error:
CREATE FUNCTION public.returnfinancials (int4) RETURNS TABLE (company_id int, financial_id_1 int, financial_id_2 int, financial_id_3 int)
as
$$
SELECT t.* FROM crosstab(
'
select company_id, row_number() OVER (ORDER BY year DESC) AS rn2, id
from
(select i.company_id, year, f.id, f.created_at,
row_number() OVER (PARTITION BY year ORDER BY year DESC, f.created_at DESC NULLS LAST) AS rn
from
public.interactions i
inner join public.financials f on f.interaction_id = i.id
where company_id = $1
) t1
where rn= 1 limit 3
'
) AS t (company_id int, financial_id_1 int, financial_id_2 int, financial_id_3 int);
$$
LANGUAGE 'sql'
Call:
select * from returnfinancials(23)
Throws:
ERROR: there is no parameter $1
Where: SQL function "returnfinancials" statement 1
Line: 1
The issue is that $1 is within a text string. It's interpreted by crosstab as a query, but within the context of the crosstab function call the parameters to the calling function are not visible. As crosstab its self passes no parameters to the query when it executes it, you get an error.
To solve this you should substitute the parameter value into the query string you pass to crosstab.
In your specific case it's OK to just substitute directly because the parameter is an integer:
'.... where company_id = '||$1||' .... '
but in general you should be careful about SQL injection and it's cleanest and safest to consistently quote your parameters. Note that '11' is a valid integer literal in SQL; it's always legal to quote an identifier, it's just optional for numbers.
So instead, even for numbers, I suggest that you use:
'.... where company_id = '||quote_literal($1)||' ....'
or use the format function to construct the string:
format('.... where company_id = %L ....', $1)
That way if someone later changes company_id to a non-numeric type you don't get a pretty SQL injection hole.
Try replace
where company_id = $1
by
where company_id = '||$1||'

Getting an "syntax error unexpected IF" when using IF statement

SELECT IF((SELECT id FROM users where store='XXX' limit 1) IS NULL, null, (SELECT id FROM users where store='XXX' limit 1)) INTO #user_id;
select #user_id;
INSERT INTO `orders`(`user_id`)VALUES(#user_id);
I need is that when #user_id is NULL I don't want to insert into my table orders. If I put an if else statement above the insertion statement,I'll get an error saying that "syntax error unexpected IF".
Use IFNULL function, this way:
SELECT IFNULL(condition, value_if_condition_is_null)
In your query, something like:
SELECT IFNULL((SELECT id FROM users where store='XXX' limit 1), (SELECT id FROM users where store='XXX' limit 1))) INTO #user_id;